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

📄 sdbms_datastruct.cpp

📁 使用yacc的一个例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	CSdbms_Role *pStack[100];		//栈大小设为100
	CSdbms_Role *pTop;			//栈顶元素,=pStack[pTop]
	CSdbms_Role *pRole1=NULL;		//表示子角色
	CSdbms_Role *pRole2=NULL;		//表示父角色
	CSdbms_Role *pPreBrother=NULL;//表示子角色的前一个兄弟
//	CSdbms_Role *pParent=NULL;	//表示子角色的父角色
	int	 nTop = 0;			//栈顶指针
	bool bFoundChild=false;	//表示是否找到子角色
	bool bFoundParent=false;//表示是否找到父角色

	pStack[nTop] = m_pRole;
	while	(nTop < 100)	//当栈没溢出
	{
		pTop = pStack[nTop];
		if	(pTop == NULL)	//退栈操作
		{
			if	(nTop == 0)
				break;		//退出循环
			else
			{
				nTop--;
				pTop = pStack[nTop];
				pStack[nTop] = pStack[nTop]->m_pFirstChildRole;	//压入右结点
				if	(pStack[nTop] == NULL)
					continue;
				if	(strChildRoleName.CompareNoCase(pStack[nTop]->m_strRoleName) == 0)	//查找子角色
				{
//					pParent = pTop;			//得到子角色的父角色
					pRole1  = pStack[nTop];	//得到子角色指针
					bFoundChild = true;

					if	(bFoundParent)
						break;
				}
			}
		}
		else
		{
			if	(strParentRoleName.CompareNoCase(pTop->m_strRoleName) == 0)	//查找父角色
			{
				pRole2 = pTop;		//得到父角色指针
				bFoundParent = true;

				if	(bFoundChild)
					break;
			}
//		else	
//		{
			nTop++;
			pStack[nTop] = pTop->m_pNextBrotherRole;	//压入左结点
			if	(pStack[nTop] == NULL)
				continue;
			if	(strChildRoleName.CompareNoCase(pStack[nTop]->m_strRoleName) == 0)	//查找子角色
			{
				pPreBrother = pTop;		//得到子角色的上一个兄弟结点
				pRole1  = pStack[nTop];	//得到子角色的指针
				bFoundChild = true;

				if	(bFoundParent)
					break;
			}
		}
	}

	if	(nTop >= 100)
	{
		g_msg.ThrowErrorMsg("栈溢出");
		return	FALSE;
	}

	if	(nTop == 0)		
	{
		if	(!bFoundChild)	//没找到子角色
		{
			sprintf(g_strMsg, "角色%s不存在", strChildRoleName);
			g_msg.ThrowErrorMsg(g_strMsg);
		}
		if	(!bFoundParent)	//没找到父角色
		{
			sprintf(g_strMsg, "角色%s不存在", strParentRoleName);
			g_msg.ThrowErrorMsg(g_strMsg);
		}
		return	FALSE;
	}

	ASSERT(pRole1 && pRole2);

	if	(pRole1->IsAncestorOf(pRole2))	//判断已有的子孙关系
	{
		sprintf(g_strMsg, "角色%s是角色%s的祖先, 设置失败", strChildRoleName, strParentRoleName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}

	//调整角色树
	if	(pRole1->m_pParentRole)		//子角色是它原来父角色的第一个孩子
	{
		if	(pPreBrother)
			pPreBrother->m_pNextBrotherRole = pRole1->m_pNextBrotherRole;
		else
			pRole1->m_pParentRole->m_pFirstChildRole = pRole1->m_pNextBrotherRole;
		pRole1->m_pNextBrotherRole = NULL;
	}
	else
	{
		ASSERT(pPreBrother);	//子角色不是它原来父角色的第一个孩子
		pPreBrother->m_pNextBrotherRole = pRole1->m_pNextBrotherRole;
		pRole1->m_pNextBrotherRole = NULL;
	}

	if	(pRole2->m_pFirstChildRole == NULL)	
	{							//成为父角色的第一个孩子
		pRole2->m_pFirstChildRole = pRole1;
	}
	else						//成为父角色的最后一个孩子
	{
		CSdbms_Role *pTemp = pRole2;
		pTemp = pTemp->m_pFirstChildRole;
		while (pTemp->m_pNextBrotherRole != NULL)
			pTemp = pTemp->m_pNextBrotherRole;
		pTemp->m_pNextBrotherRole = pRole1;
	}
	pRole1->m_pParentRole = pRole2;	//设置父角色指针

	//返回父、子角色指针
	*ppParentRole = pRole2;
	*ppChildRole  = pRole1;
	return	TRUE;
}

/**********************************************************************
功能:调整角色树,被DropRole调用
算法:strRoleName的子树上升一层
***********************************************************************/
BOOL CSdbms_Database::AdjustRoleTree(CString strRoleName, CSdbms_Role **ppRole)
{
	//非递归先序查找角色
	CSdbms_Role *pStack[100];		//栈大小设为100
	CSdbms_Role *pTop;			//栈顶元素,=pStack[pTop]
	CSdbms_Role *pPreBrother=NULL;//角色的前一个兄弟
//	CSdbms_Role *pParent=NULL;	//角色的父角色
	int	nTop = 0;			//栈顶指针

	pStack[nTop] = m_pRole;
	while	(nTop < 100)	//当栈没溢出
	{
		pTop = pStack[nTop];
		if	(pTop == NULL)	//退栈操作
		{
			if	(nTop == 0)
			{
				sprintf(g_strMsg, "角色%s不存在", strRoleName);
				g_msg.ThrowErrorMsg(g_strMsg);	//没找到这个角色
				return	FALSE;
			}
			else
			{
				nTop--;
				pTop = pStack[nTop];
				pStack[nTop] = pStack[nTop]->m_pFirstChildRole;	//压入右结点
//				pParent = pTop;		//保存父结点
				pPreBrother = NULL;	//因为它是第一个孩子,所以没有上一个兄弟结点
			}
		}
		else if	(strRoleName.CompareNoCase(pTop->m_strRoleName) == 0)	//比较
		{
			CSdbms_Role *pNextBrother = pTop->m_pNextBrotherRole;		//下一个兄弟
			CSdbms_Role *pFirstChild = pTop->m_pFirstChildRole;		//第一个孩子
			CSdbms_Role *pLastChild = pFirstChild;					//最后一个孩子
			CSdbms_Role *pPreChild = pLastChild;
			while (pLastChild)
			{
				pPreChild = pLastChild;
				pLastChild->m_pParentRole = pTop->m_pParentRole;
				pLastChild = pLastChild->m_pNextBrotherRole;
			}
			pLastChild = pPreChild;

			//所有孩子上移一层
			if	(pPreBrother == NULL)
			{
				ASSERT(pTop->m_pParentRole);
//				pParent->m_pFirstChildRole = pFirstChild;
				pTop->m_pParentRole->m_pFirstChildRole = pFirstChild;
				if	(pLastChild)
					pLastChild->m_pNextBrotherRole = pNextBrother;
			}
			else
			{
				pPreBrother->m_pNextBrotherRole = pFirstChild;
				pLastChild->m_pNextBrotherRole = pNextBrother;
			}

			break;
		}
		else	
		{
			nTop++;
			pStack[nTop] = pTop->m_pNextBrotherRole;	//压入左结点
			pPreBrother = pTop;
		}
	}

	if	(nTop >= 100)
	{
		g_msg.ThrowErrorMsg("栈溢出");
		return	FALSE;
	}

	ASSERT(nTop != 0);
	ASSERT(pTop != NULL);

	pTop->m_pFirstChildRole = NULL;
	pTop->m_pNextBrotherRole = NULL;
	*ppRole = pTop;
	return	TRUE;
}

/**********************************************************************
功能:把用户加到角色中
***********************************************************************/
BOOL CSdbms_Database::AddUserToRole(CSdbms_User *pUser, CString strRoleName)
{
	//检查角色名是否已存在
	CSdbms_Role *pRole = NULL;
	if	(!GetRole(strRoleName, &pRole))
	{
		sprintf(g_strMsg, "角色%s不存在", strRoleName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}

	ASSERT(pUser && pRole);

	CSdbms_RoleUser *pNewRoleUser = new CSdbms_RoleUser;
	pNewRoleUser->m_pRole = pRole;
	pNewRoleUser->m_pUser = pUser;

	if	(InsertRoleUserList(pNewRoleUser))
		VERIFY(InsertUserRoleList(pNewRoleUser));
	else
		delete pNewRoleUser;

	sprintf(g_strMsg, "用户%s成功加到角色%s中", pUser->m_strUserName, strRoleName);
	g_msg.ThrowSuccessMsg(g_strMsg);
	return	TRUE;
}


/**********************************************************************
功能:把用户从角色中删除
***********************************************************************/
BOOL CSdbms_Database::DelUserFromRole(CSdbms_User *pUser, CString strRoleName)
{
	//检查角色名是否已存在
	CSdbms_Role *pRole = NULL;
	if	(!GetRole(strRoleName, &pRole))
	{
		sprintf(g_strMsg, "角色%s不存在", strRoleName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}

	ASSERT(pUser && pRole);

	CSdbms_RoleUser *pRoleUser1 = RemoveRoleUserList(pUser, pRole);
	CSdbms_RoleUser *pRoleUser2 = RemoveUserRoleList(pUser, pRole);
	ASSERT(pRoleUser1 == pRoleUser2);

	if	(pRoleUser1)
	{
		//收回pRoleUser1授权的对象权限
		VERIFY(Revoke(pRoleUser1));

		delete pRoleUser1;

		sprintf(g_strMsg, "用户%s成功的从角色%s中删除", pUser->m_strUserName, strRoleName);
		g_msg.ThrowSuccessMsg(g_strMsg);

		return	TRUE;
	}
	else
		return	FALSE;
}

/**********************************************************************
功能:删除用户的所有角色
***********************************************************************/
BOOL CSdbms_Database::DelAllRole(CSdbms_User *pUser)
{
	ASSERT(pUser);

	CSdbms_RoleUser *pRoleUser;
	POSITION pos = pUser->m_pos;
	POSITION prepos;
	while (pos != NULL)
	{
		prepos = pos;
		pRoleUser = m_UserRoleList.GetNext(pos);
		if	(pRoleUser->m_pUser->m_nUserID != pUser->m_nUserID)
			break;
		else
		{
			m_UserRoleList.RemoveAt(prepos);	//从用户角色表中删除

			//从角色用户表中删除
			VERIFY(RemoveRoleUserList(pUser, pRoleUser->m_pRole) == pRoleUser);
/*
			POSITION pos2 = m_RoleUserList.Find(pRoleUser);
			ASSERT(pos2);
			prepos = pos2;
			if	(pRoleUser->m_pRole->m_pos == pos2)	//这个用户是这个角色的第一个用户
			{
				m_RoleUserList.GetNext(pos2);
				if	(m_RoleUserList.GetAt(pos2)->m_pRole->m_nRoleID != pRoleUser->m_pRole->m_nRoleID)
					pRoleUser->m_pRole->m_pos = NULL;	//这个角色没有其它用户了
				else
					pRoleUser->m_pRole->m_pos = pos2;	//指向这个角色的下一个用户
			}
			m_RoleUserList.RemoveAt(prepos);	//从角色用户表中删除
*/
			//收回pRoleUser授权的对象权限
			VERIFY(Revoke(pRoleUser));

			delete pRoleUser;
		}
	}

	pUser->m_pos = NULL;		//设置指针为NULL,因为用户已不属于任何角色
	sprintf(g_strMsg, "用户%s成功的从所有的角色中删除", pUser->m_strUserName);
	g_msg.ThrowSuccessMsg(g_strMsg);

	return	TRUE;
}

/**********************************************************************
功能:给一个角色授权系统权限
参数:nSystemRight--系统权限ID
	  strRoleName--被授权的角色名
	  nGrantUserID--授权给角色的用户ID
***********************************************************************/
BOOL CSdbms_Database::Grant(SystemRight nSystemRight, CString strRoleName, UINT nGrantUserID)
{
	//检查角色名是否已存在
	CSdbms_Role *pRole = NULL;
	if	(!GetRole(strRoleName, &pRole))
	{
		sprintf(g_strMsg, "角色%s不存在", strRoleName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}

	ASSERT(pRole);

	return	pRole->Grant(nSystemRight, nGrantUserID);
}

/**********************************************************************
功能:给一个角色收回系统权限授权
参数:nSystemRight--系统权限ID
	  strRoleName --被收回授权的角色名
	  nGrantUserID--授权给角色的用户ID
***********************************************************************/
BOOL CSdbms_Database::Revoke(SystemRight nSystemRight, CString strRoleName, UINT nGrantUserID)
{
	//检查角色名是否已存在
	CSdbms_Role *pRole = NULL;
	if	(!GetRole(strRoleName, &pRole))
	{
		sprintf(g_strMsg, "角色%s不存在", strRoleName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}

	ASSERT(pRole);

	return	pRole->Revoke(nSystemRight, nGrantUserID);
}

/**********************************************************************
功能:给角色增加一个对象权限
参数:	pUser			--	授权用户
		nObjectRight	--	要授予的对象权限
		strTableName	--	权限作用的对象的表名
		strFieldName	--	权限作用的对象的列名
		strRoleName		--	被授权的角色名
		bCanGrant		--	角色可否把权限授予给别人
		pCondition		--	权限的谓词条件的语法树
***********************************************************************/
BOOL CSdbms_Database::Grant(CSdbms_User *pUser, ObjectRight nObjectRight, CString strTableName, 
				CString strFieldName, CString strRoleName,BOOL bCanGrant/*=FALSE*/, CSdbms_Condition *pCondition/*=NULL*/)
{
	ASSERT(pUser);

	//检查被授权角色名是否已存在
	CSdbms_Role *pRole = NULL;
	if	(!GetRole(strRoleName, &pRole))
	{
		sprintf(g_strMsg, "角色%s不存在", strRoleName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}
	ASSERT(pRole);	

	//得到表内码
	CSdbms_Table *pTable=NULL;
	if	(!GetTable(strTableName, &pTable))
	{
		sprintf(g_strMsg, "数据库%s中没有表名%s", m_strDBName, strTableName);
		g_msg.ThrowErrorMsg(g_strMsg);
		return	FALSE;
	}
	ASSERT(pTable);

	//得到列内码。若列名为空,表示针对表中的所有列
	CSdbms_Field *pField=NULL;
	bool bOnlyOneField=false;
	if	(!strFieldName.IsEmpty())
	{
		if	(!pTable->GetField(strFieldName, &pField))

⌨️ 快捷键说明

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