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

📄 dbcommands.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * dbcommands.c * * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.35.2.1 1999/08/02 05:56:58 scrappy Exp $ * *------------------------------------------------------------------------- */#include <signal.h>#include <sys/stat.h>#include "postgres.h"#include "access/heapam.h"#include "catalog/catname.h"#include "catalog/pg_database.h"#include "catalog/pg_shadow.h"#include "commands/dbcommands.h"#include "miscadmin.h"#include "tcop/tcopprot.h"#include "utils/syscache.h"/* non-export function prototypes */static void check_permissions(char *command, char *dbpath, char *dbname,				  Oid *dbIdP, int4 *userIdP);static HeapTuple get_pg_dbtup(char *command, char *dbname, Relation dbrel);static void stop_vacuum(char *dbpath, char *dbname);voidcreatedb(char *dbname, char *dbpath, int encoding, CommandDest dest){	Oid			db_id;	int4		user_id;	char		buf[512];	char	   *lp,				loc[512];	/*	 * If this call returns, the database does not exist and we're allowed	 * to create databases.	 */	check_permissions("createdb", dbpath, dbname, &db_id, &user_id);	/* close virtual file descriptors so we can do system() calls */	closeAllVfds();	/* Now create directory for this new database */	if ((dbpath != NULL) && (strcmp(dbpath, dbname) != 0))	{		if (*(dbpath + strlen(dbpath) - 1) == SEP_CHAR)			*(dbpath + strlen(dbpath) - 1) = '\0';		snprintf(loc, 512, "%s%c%s", dbpath, SEP_CHAR, dbname);	}	else		strcpy(loc, dbname);	lp = ExpandDatabasePath(loc);	if (lp == NULL)		elog(ERROR, "Unable to locate path '%s'"			 "\n\tThis may be due to a missing environment variable"			 " in the server", loc);	if (mkdir(lp, S_IRWXU) != 0)		elog(ERROR, "Unable to create database directory '%s'", lp);	snprintf(buf, 512, "%s %s%cbase%ctemplate1%c* %s",			 COPY_CMD, DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, lp);	system(buf);	snprintf(buf, 512,		   "insert into pg_database (datname, datdba, encoding, datpath)"		  " values ('%s', '%d', '%d', '%s');", dbname, user_id, encoding,			 loc);	pg_exec_query_dest(buf, dest, false);}voiddestroydb(char *dbname, CommandDest dest){	int4		user_id;	Oid			db_id;	char	   *path,				dbpath[MAXPGPATH + 1],				buf[512];	/*	 * If this call returns, the database exists and we're allowed to	 * remove it.	 */	check_permissions("destroydb", dbpath, dbname, &db_id, &user_id);	if (!OidIsValid(db_id))		elog(FATAL, "pg_database instance has an invalid OID");	/* stop the vacuum daemon */	stop_vacuum(dbpath, dbname);	path = ExpandDatabasePath(dbpath);	if (path == NULL)		elog(ERROR, "Unable to locate path '%s'"			 "\n\tThis may be due to a missing environment variable"			 " in the server", dbpath);	/*	 * remove the pg_database tuple FIRST, this may fail due to	 * permissions problems	 */	snprintf(buf, 512,	"delete from pg_database where pg_database.oid = \'%u\'::oid", db_id);	pg_exec_query_dest(buf, dest, false);	/* drop pages for this database that are in the shared buffer cache */	DropBuffers(db_id);	/*	 * remove the data directory. If the DELETE above failed, this will	 * not be reached	 */	snprintf(buf, 512, "rm -r %s", path);	system(buf);}static HeapTupleget_pg_dbtup(char *command, char *dbname, Relation dbrel){	HeapTuple	dbtup;	HeapTuple	tup;	HeapScanDesc scan;	ScanKeyData scanKey;	ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,						   F_NAMEEQ, NameGetDatum(dbname));	scan = heap_beginscan(dbrel, 0, SnapshotNow, 1, &scanKey);	if (!HeapScanIsValid(scan))		elog(ERROR, "%s: cannot begin scan of pg_database", command);	/*	 * since we want to return the tuple out of this proc, and we're going	 * to close the relation, copy the tuple and return the copy.	 */	tup = heap_getnext(scan, 0);	if (HeapTupleIsValid(tup))		dbtup = heap_copytuple(tup);	else		dbtup = tup;	heap_endscan(scan);	return dbtup;}/* *	check_permissions() -- verify that the user is permitted to do this. * *	If the user is not allowed to carry out this operation, this routine *	elog(ERROR, ...)s, which will abort the xact.  As a side effect, the *	user's pg_user tuple OID is returned in userIdP and the target database's *	OID is returned in dbIdP. */static voidcheck_permissions(char *command,				  char *dbpath,				  char *dbname,				  Oid *dbIdP,				  int4 *userIdP){	Relation	dbrel;	HeapTuple	dbtup,				utup;	int4		dbowner = 0;	char		use_createdb;	bool		dbfound;	bool		use_super;	char	   *userName;	text	   *dbtext;	char		path[MAXPGPATH + 1];	userName = GetPgUserName();	utup = SearchSysCacheTuple(USENAME,							   PointerGetDatum(userName),							   0, 0, 0);	*userIdP = ((Form_pg_shadow) GETSTRUCT(utup))->usesysid;	use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;	use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;	/* Check to make sure user has permission to use createdb */	if (!use_createdb)	{		elog(ERROR, "user '%s' is not allowed to create/destroy databases",			 userName);	}	/* Make sure we are not mucking with the template database */	if (!strcmp(dbname, "template1"))		elog(ERROR, "%s: cannot be executed on the template database", command);	/* Check to make sure database is not the currently open database */	if (!strcmp(dbname, DatabaseName))		elog(ERROR, "%s: cannot be executed on an open database", command);	/* Check to make sure database is owned by this user */	/*	 * need the reldesc to get the database owner out of dbtup and to set	 * a write lock on it.	 */	dbrel = heap_openr(DatabaseRelationName);	if (!RelationIsValid(dbrel))		elog(FATAL, "%s: cannot open relation \"%-.*s\"",			 command, DatabaseRelationName);	/*	 * Acquire a write lock on pg_database from the beginning to avoid	 * upgrading a read lock to a write lock.  Upgrading causes long	 * delays when multiple 'createdb's or 'destroydb's are run simult.	 * -mer 7/3/91	 */	LockRelation(dbrel, AccessExclusiveLock);	dbtup = get_pg_dbtup(command, dbname, dbrel);	dbfound = HeapTupleIsValid(dbtup);	if (dbfound)	{		dbowner = (int4) heap_getattr(dbtup,									  Anum_pg_database_datdba,									  RelationGetDescr(dbrel),									  (char *) NULL);		*dbIdP = dbtup->t_data->t_oid;		dbtext = (text *) heap_getattr(dbtup,									   Anum_pg_database_datpath,									   RelationGetDescr(dbrel),									   (char *) NULL);		strncpy(path, VARDATA(dbtext), (VARSIZE(dbtext) - VARHDRSZ));		*(path + VARSIZE(dbtext) - VARHDRSZ) = '\0';	}	else		*dbIdP = InvalidOid;	heap_close(dbrel);	/*	 * Now be sure that the user is allowed to do this.	 */	if (dbfound && !strcmp(command, "createdb"))	{		elog(ERROR, "createdb: database '%s' already exists", dbname);	}	else if (!dbfound && !strcmp(command, "destroydb"))	{		elog(ERROR, "destroydb: database '%s' does not exist", dbname);	}	else if (dbfound && !strcmp(command, "destroydb")			 && dbowner != *userIdP && use_super == false)	{		elog(ERROR, "%s: database '%s' is not owned by you", command, dbname);	}	if (dbfound && !strcmp(command, "destroydb"))		strcpy(dbpath, path);}	/* check_permissions() *//* *	stop_vacuum() -- stop the vacuum daemon on the database, if one is running. */static voidstop_vacuum(char *dbpath, char *dbname){	char		filename[256];	FILE	   *fp;	int			pid;	if (strchr(dbpath, SEP_CHAR) != 0)	{		snprintf(filename, 256, "%s%cbase%c%s%c%s.vacuum",				 DataDir, SEP_CHAR, SEP_CHAR, dbname, SEP_CHAR, dbname);	}	else		snprintf(filename, 256, "%s%c%s.vacuum", dbpath, SEP_CHAR, dbname);#ifndef __CYGWIN32__	if ((fp = AllocateFile(filename, "r")) != NULL)#else	if ((fp = AllocateFile(filename, "rb")) != NULL)#endif	{		fscanf(fp, "%d", &pid);		FreeFile(fp);		if (kill(pid, SIGKILLDAEMON1) < 0)		{			elog(ERROR, "can't kill vacuum daemon (pid %d) on '%s'",				 pid, dbname);		}	}}

⌨️ 快捷键说明

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