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

📄 db.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2002 *	Sleepycat Software.  All rights reserved. *//* * Copyright (c) 1990, 1993, 1994, 1995, 1996 *	Keith Bostic.  All rights reserved. *//* * Copyright (c) 1990, 1993, 1994, 1995 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: db.c,v 11.246 2002/08/20 14:40:00 margo Exp $";#endif /* not lint */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_shash.h"#include "dbinc/db_swap.h"#include "dbinc/btree.h"#include "dbinc/hash.h"#include "dbinc/lock.h"#include "dbinc/log.h"#include "dbinc/log.h"#include "dbinc/mp.h"#include "dbinc/qam.h"#include "dbinc/txn.h"static int __db_disassociate __P((DB *));#if CONFIG_TESTstatic void __db_makecopy __P((const char *, const char *));static int  __db_testdocopy __P((DB_ENV *, const char *));static int  __qam_testdocopy __P((DB *, const char *));#endif/* * DB.C -- *	This file contains the utility functions for the DBP layer. *//* * __db_master_open -- *	Open up a handle on a master database. * * PUBLIC: int __db_master_open __P((DB *, * PUBLIC:     DB_TXN *, const char *, u_int32_t, int, DB **)); */int__db_master_open(subdbp, txn, name, flags, mode, dbpp)	DB *subdbp;	DB_TXN *txn;	const char *name;	u_int32_t flags;	int mode;	DB **dbpp;{	DB *dbp;	int ret;	/* Open up a handle on the main database. */	if ((ret = db_create(&dbp, subdbp->dbenv, 0)) != 0)		return (ret);	/*	 * It's always a btree.	 * Run in the transaction we've created.	 * Set the pagesize in case we're creating a new database.	 * Flag that we're creating a database with subdatabases.	 */	dbp->type = DB_BTREE;	dbp->pgsize = subdbp->pgsize;	F_SET(dbp, DB_AM_SUBDB);	F_SET(dbp, F_ISSET(subdbp,	    DB_AM_RECOVER | DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM));	/*	 * If there was a subdb specified, then we only want to apply	 * DB_EXCL to the subdb, not the actual file.  We only got here	 * because there was a subdb specified.	 */	LF_CLR(DB_EXCL);	LF_SET(DB_RDWRMASTER);	if ((ret = __db_dbopen(dbp, txn, name, NULL, flags, mode, PGNO_BASE_MD))	    != 0)		goto err;	/*	 * Verify that pagesize is the same on both.	 * The items in dbp were now initialized from the meta	 * page.  The items in dbp were set in __db_dbopen	 * when we either read or created the master file.	 * Other items such as checksum and encryption are	 * checked when we read the meta-page.  So we do not	 * check those here.  However, if the meta-page caused	 * chksumming to be turned on and it wasn't already, set	 * it here.	 */	if (F_ISSET(dbp, DB_AM_CHKSUM))		F_SET(subdbp, DB_AM_CHKSUM);	if (subdbp->pgsize != 0 && dbp->pgsize != subdbp->pgsize) {		ret = EINVAL;		__db_err(dbp->dbenv,		    "Different pagesize specified on existent file");		goto err;	}err:	if (ret != 0 && !F_ISSET(dbp, DB_AM_DISCARD))		__db_close_i(dbp, txn, 0);	else		*dbpp = dbp;	return (ret);}/* * __db_master_update -- *	Add/Open/Remove a subdatabase from a master database. * * PUBLIC: int __db_master_update __P((DB *, DB *, DB_TXN *, const char *, * PUBLIC:     DBTYPE, mu_action, const char *, u_int32_t)); */int__db_master_update(mdbp, sdbp, txn, subdb, type, action, newname, flags)	DB *mdbp, *sdbp;	DB_TXN *txn;	const char *subdb;	DBTYPE type;	mu_action action;	const char *newname;	u_int32_t flags;{	DB_ENV *dbenv;	DBC *dbc, *ndbc;	DBT key, data, ndata;	PAGE *p;	db_pgno_t t_pgno;	int modify, ret, t_ret;	dbenv = mdbp->dbenv;	dbc = ndbc = NULL;	p = NULL;	memset(&key, 0, sizeof(key));	memset(&data, 0, sizeof(data));	/* Might we modify the master database?  If so, we'll need to lock. */	modify = (action != MU_OPEN || LF_ISSET(DB_CREATE)) ? 1 : 0;	/*	 * Open up a cursor.  If this is CDB and we're creating the database,	 * make it an update cursor.	 */	if ((ret = mdbp->cursor(mdbp, txn, &dbc,	    (CDB_LOCKING(dbenv) && modify) ? DB_WRITECURSOR : 0)) != 0)		goto err;	/*	 * Point the cursor at the record.	 *	 * If we're removing or potentially creating an entry, lock the page	 * with DB_RMW.	 *	 * We do multiple cursor operations with the cursor in some cases and	 * subsequently access the data DBT information.  Set DB_DBT_MALLOC so	 * we don't risk modification of the data between our uses of it.	 *	 * !!!	 * We don't include the name's nul termination in the database.	 */	key.data = (void *)subdb;	key.size = (u_int32_t)strlen(subdb);	F_SET(&data, DB_DBT_MALLOC);	ret = dbc->c_get(dbc, &key, &data,	    DB_SET | ((STD_LOCKING(dbc) && modify) ? DB_RMW : 0));	/*	 * What we do next--whether or not we found a record for the	 * specified subdatabase--depends on what the specified action is.	 * Handle ret appropriately as the first statement of each case.	 */	switch (action) {	case MU_REMOVE:		/*		 * We should have found something if we're removing it.  Note		 * that in the common case where the DB we're asking to remove		 * doesn't exist, we won't get this far;  __db_subdb_remove		 * will already have returned an error from __db_open.		 */		if (ret != 0)			goto err;		/*		 * Delete the subdatabase entry first;  if this fails,		 * we don't want to touch the actual subdb pages.		 */		if ((ret = dbc->c_del(dbc, 0)) != 0)			goto err;		/*		 * We're handling actual data, not on-page meta-data,		 * so it hasn't been converted to/from opposite		 * endian architectures.  Do it explicitly, now.		 */		memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t));		DB_NTOHL(&sdbp->meta_pgno);		if ((ret =		    mdbp->mpf->get(mdbp->mpf, &sdbp->meta_pgno, 0, &p)) != 0)			goto err;		/* Free and put the page. */		if ((ret = __db_free(dbc, p)) != 0) {			p = NULL;			goto err;		}		p = NULL;		break;	case MU_RENAME:		/* We should have found something if we're renaming it. */		if (ret != 0)			goto err;		/*		 * Before we rename, we need to make sure we're not		 * overwriting another subdatabase, or else this operation		 * won't be undoable.  Open a second cursor and check		 * for the existence of newname;  it shouldn't appear under		 * us since we hold the metadata lock.		 */		if ((ret = mdbp->cursor(mdbp, txn, &ndbc, 0)) != 0)			goto err;		DB_ASSERT(newname != NULL);		key.data = (void *)newname;		key.size = (u_int32_t)strlen(newname);		/*		 * We don't actually care what the meta page of the potentially-		 * overwritten DB is;  we just care about existence.		 */		memset(&ndata, 0, sizeof(ndata));		F_SET(&ndata, DB_DBT_USERMEM | DB_DBT_PARTIAL);		if ((ret = ndbc->c_get(ndbc, &key, &ndata, DB_SET)) == 0) {			/* A subdb called newname exists.  Bail. */			ret = EEXIST;			__db_err(dbenv, "rename: database %s exists", newname);			goto err;		} else if (ret != DB_NOTFOUND)			goto err;		/*		 * Now do the put first;  we don't want to lose our		 * sole reference to the subdb.  Use the second cursor		 * so that the first one continues to point to the old record.		 */		if ((ret = ndbc->c_put(ndbc, &key, &data, DB_KEYFIRST)) != 0)			goto err;		if ((ret = dbc->c_del(dbc, 0)) != 0) {			/*			 * If the delete fails, try to delete the record			 * we just put, in case we're not txn-protected.			 */			(void)ndbc->c_del(ndbc, 0);			goto err;		}		break;	case MU_OPEN:		/*		 * Get the subdatabase information.  If it already exists,		 * copy out the page number and we're done.		 */		switch (ret) {		case 0:			if (LF_ISSET(DB_CREATE) && LF_ISSET(DB_EXCL)) {				ret = EEXIST;				goto err;			}			memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t));			DB_NTOHL(&sdbp->meta_pgno);			goto done;		case DB_NOTFOUND:			if (LF_ISSET(DB_CREATE))				break;			/*			 * No db_err, it is reasonable to remove a			 * nonexistent db.			 */			ret = ENOENT;			goto err;		default:			goto err;		}		/*		 * We need to check against the master lorder here because		 * we only want to check this if we are creating.  In the		 * case where we don't create we just want to inherit.		 */		if (F_ISSET(mdbp, DB_AM_SWAP) != F_ISSET(sdbp, DB_AM_SWAP)) {			 ret = EINVAL;			 __db_err(mdbp->dbenv,			    "Different lorder specified on existent file");			goto err;		}		/* Create a subdatabase. */		if ((ret = __db_new(dbc,		    type == DB_HASH ? P_HASHMETA : P_BTREEMETA, &p)) != 0)			goto err;		sdbp->meta_pgno = PGNO(p);		/*		 * XXX		 * We're handling actual data, not on-page meta-data, so it		 * hasn't been converted to/from opposite endian architectures.		 * Do it explicitly, now.		 */		t_pgno = PGNO(p);		DB_HTONL(&t_pgno);		memset(&ndata, 0, sizeof(ndata));		ndata.data = &t_pgno;		ndata.size = sizeof(db_pgno_t);		if ((ret = dbc->c_put(dbc, &key, &ndata, DB_KEYLAST)) != 0)			goto err;		F_SET(sdbp, DB_AM_CREATED);		break;	}err:done:	/*	 * If we allocated a page: if we're successful, mark the page dirty	 * and return it to the cache, otherwise, discard/free it.	 */	if (p != NULL) {		if (ret == 0) {			if ((t_ret =			    mdbp->mpf->put(mdbp->mpf, p, DB_MPOOL_DIRTY)) != 0)				ret = t_ret;			/*			 * Since we cannot close this file until after			 * transaction commit, we need to sync the dirty			 * pages, because we'll read these directly from			 * disk to open.			 */			if ((t_ret = mdbp->sync(mdbp, 0)) != 0 && ret == 0)				ret = t_ret;		} else			(void)mdbp->mpf->put(mdbp->mpf, p, 0);	}	/* Discard the cursor(s) and data. */	if (data.data != NULL)		__os_ufree(dbenv, data.data);	if (dbc != NULL && (t_ret = dbc->c_close(dbc)) != 0 && ret == 0)		ret = t_ret;	if (ndbc != NULL && (t_ret = ndbc->c_close(ndbc)) != 0 && ret == 0)		ret = t_ret;	return (ret);}/* * __db_dbenv_setup -- *	Set up the underlying environment during a db_open. * * PUBLIC: int __db_dbenv_setup __P((DB *, * PUBLIC:     DB_TXN *, const char *, u_int32_t, u_int32_t)); */int__db_dbenv_setup(dbp, txn, name, id, flags)	DB *dbp;	DB_TXN *txn;	const char *name;	u_int32_t id;	u_int32_t flags;{	DB *ldbp;	DBT pgcookie;	DB_ENV *dbenv;	DB_MPOOL *dbmp;	DB_MPOOLFILE *mpf;	DB_PGINFO pginfo;	u_int32_t maxid;	int ftype, ret;	dbenv = dbp->dbenv;	/* If we don't yet have an environment, it's time to create it. */	if (!F_ISSET(dbenv, DB_ENV_OPEN_CALLED)) {		/* Make sure we have at least DB_MINCACHE pages in our cache. */		if (dbenv->mp_gbytes == 0 &&		    dbenv->mp_bytes < dbp->pgsize * DB_MINPAGECACHE &&		    (ret = dbenv->set_cachesize(		    dbenv, 0, dbp->pgsize * DB_MINPAGECACHE, 0)) != 0)			return (ret);		if ((ret = dbenv->open(dbenv, NULL, DB_CREATE |		    DB_INIT_MPOOL | DB_PRIVATE | LF_ISSET(DB_THREAD), 0)) != 0)			return (ret);	}

⌨️ 快捷键说明

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