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

📄 tcl_db.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
	/*	 * If it is a QUEUE or RECNO database, the key is a record number	 * and must be setup up to contain a db_recno_t.  Otherwise the	 * key is a "string".	 */	(void)dbp->get_type(dbp, &type);	/*	 * We need to determine where the end of required args are.  If we	 * are using a QUEUE/RECNO db and -append, then there is just one	 * req arg (data).  Otherwise there are two (key data).	 *	 * We preparse the list to determine this since we need to know	 * to properly check # of args for other options below.	 */	end = objc - 2;	if (type == DB_QUEUE || type == DB_RECNO) {		i = 2;		while (i < objc - 1) {			if (Tcl_GetIndexFromObj(interp, objv[i++], dbputapp,			    "option", TCL_EXACT, &optindex) != TCL_OK)				continue;			switch ((enum dbputapp)optindex) {			case DBPUT_APPEND0:				end = objc - 1;				break;			}		}	}	Tcl_ResetResult(interp);	/*	 * Get the command name index from the object based on the options	 * defined above.	 */	i = 2;	auto_commit = 0;	while (i < end) {		if (Tcl_GetIndexFromObj(interp, objv[i],		    dbputopts, "option", TCL_EXACT, &optindex) != TCL_OK)			return (IS_HELP(objv[i]));		i++;		switch ((enum dbputopts)optindex) {#if CONFIG_TEST		case DBGET_NODUPDATA:			FLAG_CHECK(flag);			flag = DB_NODUPDATA;			break;#endif		case DBPUT_TXN:			if (i > (end - 1)) {				Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");				result = TCL_ERROR;				break;			}			arg = Tcl_GetStringFromObj(objv[i++], NULL);			txn = NAME_TO_TXN(arg);			if (txn == NULL) {				snprintf(msg, MSG_SIZE,				    "Put: Invalid txn: %s\n", arg);				Tcl_SetResult(interp, msg, TCL_VOLATILE);				result = TCL_ERROR;			}			break;		case DBPUT_AUTO_COMMIT:			auto_commit = 1;			break;		case DBPUT_APPEND:			FLAG_CHECK(flag);			flag = DB_APPEND;			break;		case DBPUT_NOOVER:			FLAG_CHECK(flag);			flag = DB_NOOVERWRITE;			break;		case DBPUT_PART:			if (i > (end - 1)) {				Tcl_WrongNumArgs(interp, 2, objv,				    "?-partial {offset length}?");				result = TCL_ERROR;				break;			}			/*			 * Get sublist as {offset length}			 */			result = Tcl_ListObjGetElements(interp, objv[i++],			    &elemc, &elemv);			if (elemc != 2) {				Tcl_SetResult(interp,				    "List must be {offset length}", TCL_STATIC);				result = TCL_ERROR;				break;			}			data.flags = DB_DBT_PARTIAL;			result = _GetUInt32(interp, elemv[0], &data.doff);			if (result != TCL_OK)				break;			result = _GetUInt32(interp, elemv[1], &data.dlen);			/*			 * NOTE: We don't check result here because all we'd			 * do is break anyway, and we are doing that.  If you			 * add code here, you WILL need to add the check			 * for result.  (See the check for save.doff, a few			 * lines above and copy that.)			 */			break;		}		if (result != TCL_OK)			break;	}	if (auto_commit)		flag |= DB_AUTO_COMMIT;	if (result == TCL_ERROR)		return (result);	/*	 * If we are a recno db and we are NOT using append, then the 2nd	 * last arg is the key.	 */	if (type == DB_QUEUE || type == DB_RECNO) {		key.data = &recno;		key.ulen = key.size = sizeof(db_recno_t);		key.flags = DB_DBT_USERMEM;		if (flag == DB_APPEND)			recno = 0;		else {			result = _GetUInt32(interp, objv[objc-2], &recno);			if (result != TCL_OK)				return (result);		}	} else {		ret = _CopyObjBytes(interp, objv[objc-2], &ktmp,		    &key.size, &freekey);		if (ret != 0) {			result = _ReturnSetup(interp, ret,			    DB_RETOK_DBPUT(ret), "db put");			return (result);		}		key.data = ktmp;	}	ret = _CopyObjBytes(interp, objv[objc-1], &dtmp,	    &data.size, &freedata);	if (ret != 0) {		result = _ReturnSetup(interp, ret,		    DB_RETOK_DBPUT(ret), "db put");		goto out;	}	data.data = dtmp;	_debug_check();	ret = dbp->put(dbp, txn, &key, &data, flag);	result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put");	if (ret == 0 &&	    (type == DB_RECNO || type == DB_QUEUE) && flag == DB_APPEND) {		res = Tcl_NewLongObj((long)recno);		Tcl_SetObjResult(interp, res);	}out:	if (freedata)		(void)__os_free(dbp->dbenv, dtmp);	if (freekey)		(void)__os_free(dbp->dbenv, ktmp);	return (result);}/* * tcl_db_get -- */static inttcl_DbGet(interp, objc, objv, dbp, ispget)	Tcl_Interp *interp;		/* Interpreter */	int objc;			/* How many arguments? */	Tcl_Obj *CONST objv[];		/* The argument objects */	DB *dbp;			/* Database pointer */	int ispget;			/* 1 for pget, 0 for get */{	static char *dbgetopts[] = {#if CONFIG_TEST		"-dirty",		"-multi",#endif		"-consume",		"-consume_wait",		"-get_both",		"-glob",		"-partial",		"-recno",		"-rmw",		"-txn",		"--",		NULL	};	enum dbgetopts {#if CONFIG_TEST		DBGET_DIRTY,		DBGET_MULTI,#endif		DBGET_CONSUME,		DBGET_CONSUME_WAIT,		DBGET_BOTH,		DBGET_GLOB,		DBGET_PART,		DBGET_RECNO,		DBGET_RMW,		DBGET_TXN,		DBGET_ENDARG	};	DBC *dbc;	DBT key, pkey, data, save;	DBTYPE type;	DB_TXN *txn;	Tcl_Obj **elemv, *retlist;	void *dtmp, *ktmp;	u_int32_t flag, cflag, isdup, mflag, rmw;	int bufsize, elemc, end, endarg, freekey, freedata, i;	int optindex, result, ret, useglob, useprecno, userecno;	char *arg, *pattern, *prefix, msg[MSG_SIZE];	db_recno_t precno, recno;	result = TCL_OK;	freekey = freedata = 0;	cflag = endarg = flag = mflag = rmw = 0;	useglob = userecno = useprecno = 0;	txn = NULL;	pattern = prefix = NULL;	if (objc < 3) {		Tcl_WrongNumArgs(interp, 2, objv, "?-args? key");		return (TCL_ERROR);	}	memset(&key, 0, sizeof(key));	memset(&data, 0, sizeof(data));	memset(&save, 0, sizeof(save));	/* For the primary key in a pget call. */	memset(&pkey, 0, sizeof(pkey));	/*	 * Get the command name index from the object based on the options	 * defined above.	 */	i = 2;	(void)dbp->get_type(dbp, &type);	end = objc;	while (i < end) {		if (Tcl_GetIndexFromObj(interp, objv[i], dbgetopts, "option",		    TCL_EXACT, &optindex) != TCL_OK) {			arg = Tcl_GetStringFromObj(objv[i], NULL);			if (arg[0] == '-') {				result = IS_HELP(objv[i]);				goto out;			} else				Tcl_ResetResult(interp);			break;		}		i++;		switch ((enum dbgetopts)optindex) {#if CONFIG_TEST		case DBGET_DIRTY:			rmw |= DB_DIRTY_READ;			break;		case DBGET_MULTI:			mflag |= DB_MULTIPLE;			result = Tcl_GetIntFromObj(interp, objv[i], &bufsize);			if (result != TCL_OK)				goto out;			i++;			break;#endif		case DBGET_BOTH:			/*			 * Change 'end' and make sure we aren't already past			 * the new end.			 */			if (i > objc - 2) {				Tcl_WrongNumArgs(interp, 2, objv,				    "?-get_both key data?");				result = TCL_ERROR;				break;			}			end = objc - 2;			FLAG_CHECK(flag);			flag = DB_GET_BOTH;			break;		case DBGET_TXN:			if (i >= end) {				Tcl_WrongNumArgs(interp, 2, objv, "?-txn id?");				result = TCL_ERROR;				break;			}			arg = Tcl_GetStringFromObj(objv[i++], NULL);			txn = NAME_TO_TXN(arg);			if (txn == NULL) {				snprintf(msg, MSG_SIZE,				    "Get: Invalid txn: %s\n", arg);				Tcl_SetResult(interp, msg, TCL_VOLATILE);				result = TCL_ERROR;			}			break;		case DBGET_GLOB:			useglob = 1;			end = objc - 1;			break;		case DBGET_CONSUME:			FLAG_CHECK(flag);			flag = DB_CONSUME;			break;		case DBGET_CONSUME_WAIT:			FLAG_CHECK(flag);			flag = DB_CONSUME_WAIT;			break;		case DBGET_RECNO:			end = objc - 1;			userecno = 1;			if (type != DB_RECNO && type != DB_QUEUE) {				FLAG_CHECK(flag);				flag = DB_SET_RECNO;			}			break;		case DBGET_RMW:			rmw |= DB_RMW;			break;		case DBGET_PART:			end = objc - 1;			if (i == end) {				Tcl_WrongNumArgs(interp, 2, objv,				    "?-partial {offset length}?");				result = TCL_ERROR;				break;			}			/*			 * Get sublist as {offset length}			 */			result = Tcl_ListObjGetElements(interp, objv[i++],			    &elemc, &elemv);			if (elemc != 2) {				Tcl_SetResult(interp,				    "List must be {offset length}", TCL_STATIC);				result = TCL_ERROR;				break;			}			save.flags = DB_DBT_PARTIAL;			result = _GetUInt32(interp, elemv[0], &save.doff);			if (result != TCL_OK)				break;			result = _GetUInt32(interp, elemv[1], &save.dlen);			/*			 * NOTE: We don't check result here because all we'd			 * do is break anyway, and we are doing that.  If you			 * add code here, you WILL need to add the check			 * for result.  (See the check for save.doff, a few			 * lines above and copy that.)			 */			break;		case DBGET_ENDARG:			endarg = 1;			break;		} /* switch */		if (result != TCL_OK)			break;		if (endarg)			break;	}	if (result != TCL_OK)		goto out;	if (type == DB_RECNO || type == DB_QUEUE)		userecno = 1;	/*	 * Check args we have left versus the flags we were given.	 * We might have 0, 1 or 2 left.  If we have 0, it must	 * be DB_CONSUME*, if 2, then DB_GET_BOTH, all others should	 * be 1.	 */	if (((flag == DB_CONSUME || flag == DB_CONSUME_WAIT) && i != objc) ||	    (flag == DB_GET_BOTH && i != objc - 2)) {		Tcl_SetResult(interp,		    "Wrong number of key/data given based on flags specified\n",		    TCL_STATIC);		result = TCL_ERROR;		goto out;	} else if (flag == 0 && i != objc - 1) {		Tcl_SetResult(interp,		    "Wrong number of key/data given\n", TCL_STATIC);		result = TCL_ERROR;		goto out;	}	/*	 * XXX	 * We technically shouldn't be looking inside the dbp like this,	 * but this is the only way to figure out whether the primary	 * key should also be a recno.	 */	if (ispget) {		if (dbp->s_primary != NULL &&		    (dbp->s_primary->type == DB_RECNO ||		    dbp->s_primary->type == DB_QUEUE))			useprecno = 1;	}	/*	 * Check for illegal combos of options.	 */	if (useglob && (userecno || flag == DB_SET_RECNO ||	    type == DB_RECNO || type == DB_QUEUE)) {		Tcl_SetResult(interp,		    "Cannot use -glob and record numbers.\n",		    TCL_STATIC);		result = TCL_ERROR;		goto out;	}	if (useglob && flag == DB_GET_BOTH) {		Tcl_SetResult(interp,		    "Only one of -glob or -get_both can be specified.\n",		    TCL_STATIC);		result = TCL_ERROR;		goto out;	}	if (useglob)		pattern = Tcl_GetStringFromObj(objv[objc - 1], NULL);	/*	 * This is the list we return	 */	retlist = Tcl_NewListObj(0, NULL);	save.flags |= DB_DBT_MALLOC;	/*	 * isdup is used to know if we support duplicates.  If not, we	 * can just do a db->get call and avoid using cursors.	 * XXX	 * When there is a db->get_flags method, it should be used.	 * isdup = dbp->get_flags(dbp) & DB_DUP;	 * For now we illegally peek.	 * XXX	 */	isdup = dbp->flags & DB_AM_DUP;	/*	 * If the database doesn't support duplicates or we're performing	 * ops that don't require returning multiple items, use DB->get	 * instead of a cursor operation.	 */	if (pattern == NULL && (isdup == 0 || mflag != 0 ||	    flag == DB_SET_RECNO || flag == DB_GET_BOTH ||	    flag == DB_CONSUME || flag == DB_CONSUME_WAIT)) {		if (flag == DB_GET_BOTH) {			if (userecno) {				result = _GetUInt32(interp,				    objv[(objc - 2)], &recno);				if (result == TCL_OK) {					key.data = &recno;					key.size = sizeof(db_recno_t);				} else					goto out;			} else {				/*				 * Some get calls (SET_*) can change the				 * key pointers.  So, we need to store				 * the allocated key space in a tmp.				 */				ret = _CopyObjBytes(interp, objv[objc-2],				    &ktmp, &key.size, &freekey);				if (ret != 0) {					result = _ReturnSetup(interp, ret,					    DB_RETOK_DBGET(ret), "db get");					goto out;				}				key.data = ktmp;			}			/*			 * Already checked args above.  Fill in key and save.			 * Save is used in the dbp->get call below to fill in			 * data.			 *			 * If the "data" here is really a primary key--that			 * is, if we're in a pget--and that primary key			 * is a recno, treat it appropriately as an int.			 */			if (useprecno) {				result = _GetUInt32(interp,				    objv[objc - 1], &precno);				if (result == TCL_OK) {					save.data = &precno;					save.size = sizeof(db_recno_t);				} else					goto out;			} else {				ret = _CopyObjBytes(interp, objv[objc-1],				    &dtmp, &save.size, &freedata);				if (ret != 0) {					result = _ReturnSetup(interp, ret,					    DB_RETOK_DBGET(ret), "db get");					goto out;				}				save.data = dtmp;			}		} else if (flag != DB_CONSUME && flag != DB_CONSUME_WAIT) {			if (userecno) {				result = _GetUInt32(				    interp, objv[(objc - 1)], &recno);				if (result == TCL_OK) {					key.data = &recno;					key.size = sizeof(db_recno_t);				} else					goto out;			} else {				/*				 * Some get calls (SET_*) can change the				 * key pointers.  So, we need to store				 * the allocated key space in a tmp.				 */				ret = _CopyObjBytes(interp, objv[objc-1],				    &ktmp, &key.size, &freekey);				if (ret != 0) {					result = _ReturnSetup(interp, ret,					    DB_RETOK_DBGET(ret), "db get");					goto out;				}				key.data = ktmp;			}			if (mflag & DB_MULTIPLE) {				if ((ret = __os_malloc(dbp->dbenv,				    bufsize, &save.data)) != 0) {					Tcl_SetResult(interp,					    db_strerror(ret), TCL_STATIC);					goto out;				}				save.ulen = bufsize;				F_CLR(&save, DB_DBT_MALLOC);				F_SET(&save, DB_DBT_USERMEM);			}		}		data = save;		if (ispget) {			if (flag == DB_GET_BOTH) {				pkey.data = save.data;				pkey.size = save.size;				data.data = NULL;				data.size = 0;			}			F_SET(&pkey, DB_DBT_MALLOC);			_debug_check();			ret = dbp->pget(dbp,			    txn, &key, &pkey, &data, flag | rmw);		} else {			_debug_check();			ret = dbp->get(dbp,			    txn, &key, &data, flag | rmw | mflag);		}		result = _ReturnSetup(interp, ret, DB_RETOK_DBGET(ret),		    "db get");		if (ret == 0) {			/*			 * Success.  Return a list of the form {name value}			 * If it was a recno in key.data, we need to convert			 * into a string/object representation of that recno.			 */			if (mflag & DB_MULTIPLE)				result = _SetMultiList(interp,				    retlist, &key, &data, type, flag);			else if (type == DB_RECNO || type == DB_QUEUE)				if (ispget)					result = _Set3DBTList(interp,					    retlist, &key, 1, &pkey,					    useprecno, &data);				else					result = _SetListRecnoElem(interp,					    retlist, *(db_recno_t *)key.data,					    data.data, data.size);			else {				if (ispget)					result = _Set3DBTList(interp,					    retlist, &key, 0, &pkey,					    useprecno, &data);				else					result = _SetListElem(interp, retlist,					    key.data, key.size,					    data.data, data.size);			}		}		/*		 * Free space from DBT.		 *		 * If we set DB_DBT_MALLOC, we need to free the space if		 * and only if we succeeded (and thus if DB allocated		 * anything).  If DB_DBT_MALLOC is not set, this is a bulk		 * get buffer, and needs to be freed no matter what.		 */		if (F_ISSET(&data, DB_DBT_MALLOC) && ret == 0)			__os_ufree(dbp->dbenv, data.data);		else if (!F_ISSET(&data, DB_DBT_MALLOC))			__os_free(dbp->dbenv, data.data);		if (ispget && ret == 0)			__os_ufree(dbp->dbenv, pkey.data);		if (result == TCL_OK)			Tcl_SetObjResult(interp, retlist);		goto out;	}

⌨️ 快捷键说明

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