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

📄 sdbms_datastruct.cpp

📁 使用yacc的一个例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		{
			sprintf(g_strMsg, "表%s中没有列名%s", strTableName, strFieldName);
			g_msg.ThrowErrorMsg(g_strMsg);
			return	FALSE;
		}
		bOnlyOneField = true;
		ASSERT(pField);
	}

	//预处理权限的谓词条件
	if	(pCondition)
	{
		BOOL bValue=FALSE, bCanComp=FALSE;
		
		//设置缺省表名
		pCondition->SetDefaultTableName(strTableName);

		if	(pCondition->PreTreat(&bValue, &bCanComp))	//表达式是常量
		{
			if	(bValue)	//谓词条件永真
			{
				delete pCondition;
				pCondition = NULL;
			}
			else
			{
				g_msg.ThrowErrorMsg("谓词条件永为假,GRANT失败");
				return	FALSE;
			}
		}
		else	//表达式含有列名
		{
			if	(!bCanComp)
			{
				g_msg.ThrowErrorMsg("谓词条件表达式语法错误, GRANT失败");
				return	FALSE;
			}
		}
	}

	CSdbms_RoleUser *pRoleUser1=NULL, *pRoleUser2=NULL;
	if	(g_sdbms.IsOwnDbaRole(pUser->m_nUserID))			//授权用户属于DBA角色	
		pRoleUser1 = g_sdbms.FindRoleUser(pUser, g_sdbms.GetDbaRole());
//	if	(g_sdbms.IsOwnSystemRole(pUser->m_nUserID))			//授权用户属于SYSTEM角色
//		pRoleUser2 = g_sdbms.FindRoleUser(pUser, g_sdbms.GetSystemRole());

	bool bGrant = false;
	int nCount = bOnlyOneField ? 1 : pTable->m_FieldArray.GetSize();	//判断只有一列还是要针对所有列
	for	(int i=0; i<nCount; i++)
	{
		bGrant = false;

		if	(bOnlyOneField)	//只有一列
			ASSERT(i == 0);	//只会执行一次
		else
			pField = pTable->m_FieldArray[i];

		//如果被授权角色的父角色没有此对象权限,授权失败
		CSdbms_Role *pParent = pRole->m_pParentRole;
		if	(pParent != NULL)
		{
			if	(pParent->FindObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight, pCondition) == NULL)
			{
				sprintf(g_strMsg, "因为角色%s的父角色%s没有在%s.%s.%s上的%s权限,所以不能授权",
						strRoleName, pParent->m_strRoleName, m_strDBName, 
						strTableName, pField->m_strFieldName, g_strObjectRight[nObjectRight]);
				g_msg.ThrowErrorMsg(g_strMsg);				
				continue;
			}
		}

		if	(pRoleUser1)		//用户属于DBA角色
		{
			if	(pRole->InsertORList(nObjectRight, pTable->m_nTableID, 
					pField->m_nFieldID, pRoleUser1, bCanGrant, pCondition))
			{
				bGrant = true;
				
				CSdbms_RoleObjectRight *pRight = pRoleUser1->m_pRole->m_ORList.GetHead();
				ASSERT(pRight);
				VERIFY(pRight->InsertToRoleArray(pRole));	//系统预定义角色都只有一个对象权限结点

				sprintf(g_strMsg, "用户%s成功地以DBA身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
					pUser->m_strUserName, m_strDBName, strTableName, 
					pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
				g_msg.ThrowSuccessMsg(g_strMsg);
			}
		}

/*		if	(pRoleUser2)		//用户属于SYSTEM角色
		{
			if	(pRole->InsertORList(nObjectRight, pTable->m_nTableID, 
					pField->m_nFieldID, pRoleUser2, bCanGrant, pCondition))
			{
				bGrant = true;

				CSdbms_RoleObjectRight *pRight = pRoleUser2->m_pRole->m_ORList.GetHead();
				ASSERT(pRight);
				VERIFY(pRight->InsertToRoleArray(pRole));	//系统预定义角色都只有一个对象权限结点

				sprintf(g_strMsg, "用户%s成功地以SYSTEM身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
					pUser->m_strUserName, m_strDBName, strTableName, 
					pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
				g_msg.ThrowSuccessMsg(g_strMsg);
			}
		}
*/
		//用户是不是数据库的创建者
		if	(IsDBCreator(pUser->m_nUserID))
		{
			if	(pRole->InsertORList(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, m_RoleUserList.GetHead(), bCanGrant, pCondition))
			{
				bGrant = TRUE;

				CSdbms_RoleObjectRight *pRight = m_pCreatorRole->m_ORList.GetHead();
				ASSERT(pRight);
				VERIFY(pRight->InsertToRoleArray(pRole));	//系统预定义角色都只有一个对象权限结点

				sprintf(g_strMsg, "用户%s成功地以数据库%s创建者的身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
					pUser->m_strUserName, m_strDBName, m_strDBName, strTableName, 
					pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
				g_msg.ThrowSuccessMsg(g_strMsg);
			}
		}

		//用户是不是表的创建者
		if	(pTable->IsTableCreator(pUser->m_nUserID))
		{
//			CSdbms_Role *pTemp;
//			VERIFY(GetTBCreatorRole(pTable->m_nTableID, &pTemp));
//			POSITION pos = FindRoleUser(pTemp, pUser);
			POSITION pos = FindRoleUser(pTable->m_pCreatorRole, pUser);

			if	(pRole->InsertORList(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, m_RoleUserList.GetAt(pos), bCanGrant, pCondition))
			{
				bGrant = TRUE;

				CSdbms_RoleObjectRight *pRight = pTable->m_pCreatorRole->m_ORList.GetHead();
				ASSERT(pRight);
				VERIFY(pRight->InsertToRoleArray(pRole));	//系统预定义角色都只有一个对象权限结点

				sprintf(g_strMsg, "用户%s成功地以表%s创建者的身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
					pUser->m_strUserName, strTableName, m_strDBName, 
					strTableName, pField->m_strFieldName, 
					g_strObjectRight[nObjectRight], strRoleName);
				g_msg.ThrowSuccessMsg(g_strMsg);
			}
		}

		//遍历用户所属的所有角色
		POSITION pos = pUser->m_pos;
		while (pos != NULL)
		{
			CSdbms_RoleUser *pRoleUser = m_UserRoleList.GetNext(pos);
			if	(pRoleUser->m_pUser->m_nUserID == pUser->m_nUserID)
			{
				if	(pRoleUser->m_pRole->m_nRoleID == pRole->m_nRoleID)
					continue;				//不能授权给自身

				if	(pRoleUser->m_pRole->m_strRoleName.CompareNoCase(SYSTEM_ROLE_OWNER) == 0)
					continue;				//如果是数据库创建者或表创建者,中止,遍历下一个结点

				if	(pRole->Grant(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, pRoleUser, bCanGrant, pCondition))
				{
					bGrant = TRUE;
					sprintf(g_strMsg, "用户%s成功地以%s身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
						pUser->m_strUserName, pRoleUser->m_pRole->m_strRoleName, 
						m_strDBName, strTableName, 
						pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
					g_msg.ThrowSuccessMsg(g_strMsg);
				}
			}
			else
				break;
		}

		if	(bGrant)
		{
			sprintf(g_strMsg, "成功地把作用在%s.%s.%s上的%s权限授予给了角色%s",
					m_strDBName, strTableName, 
					pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
			g_msg.ThrowSuccessMsg(g_strMsg);
		}
		else
		{
			sprintf(g_strMsg, "失败地把作用在%s.%s.%s上的%s权限授予给了角色%s",
					m_strDBName, strTableName, 
					pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
			g_msg.ThrowErrorMsg(g_strMsg);
		}
	}

	return	bGrant;
}

/**********************************************************************
功能:取消角色的一个对象权限授权
参数:	pUser			--	撤消授权的执行用户
		nObjectRight	--	要撤消授权的对象权限
		strTableName	--	权限作用的对象的表名
		strFieldName	--	权限作用的对象的列名
		strRoleName		--	被撤消授权的角色名
		bRevokeGrant	--	是否只收回授予权限,而不收回权限本身
		bRestrict		--	如果为真表示如果要收回的权限已经授权给其他用户,则该语句不能执行
		pCondition		--	权限的谓词条件的语法树
算法:	先判断角色中是否含有该对象权限,若有则再查找权限授权者,
		若授权人是该用户,则对其所有用户角色关系回收权限,
		(既然存在,则用户所属的角色权限一定仍在,则一定会回收成功)
***********************************************************************/
BOOL CSdbms_Database::Revoke(CSdbms_User *pUser, ObjectRight nObjectRight, CString strTableName, 
			CString strFieldName, CString strRoleName,BOOL bRevokeGrant/*=FALSE*/, 
			BOOL bRestrict/*=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))
		{
			sprintf(g_strMsg, "表%s中没有列名%s", strTableName, strFieldName);
			g_msg.ThrowErrorMsg(g_strMsg);
			return	FALSE;
		}
		bOnlyOneField = true;
		ASSERT(pField);
	}

	//预处理权限的谓词条件
	if	(pCondition)
	{
		BOOL bValue=FALSE, bCanComp=FALSE;
		
		//设置缺省表名
		pCondition->SetDefaultTableName(strTableName);

		if	(pCondition->PreTreat(&bValue, &bCanComp))	//表达式是常量
		{
			if	(bValue)	//谓词条件永真
			{
				delete pCondition;
				pCondition = NULL;
			}
			else
			{
				g_msg.ThrowErrorMsg("谓词条件永为假,GRANT失败");
				return	FALSE;
			}
		}
		else	//表达式含有列名
		{
			if	(!bCanComp)
			{
				g_msg.ThrowErrorMsg("谓词条件表达式语法错误, GRANT失败");
				return	FALSE;
			}
		}
	}
	
	bool bSuccess = false;
	int nCount = bOnlyOneField ? 1 : pTable->m_FieldArray.GetSize();//判断只有一列还是要针对所有列
	for	(int i=0; i<nCount; i++)
	{
		bSuccess = false;

		if	(bOnlyOneField)	//只有一列
			ASSERT(i == 0);	//只会执行一次
		else
			pField = pTable->m_FieldArray[i];

		UINT nTableID = pTable->m_nTableID;
		UINT nFieldID = pField->m_nFieldID;

		//判断角色是否有该权限
		POSITION pos = pRole->FindObjectRight(nTableID, nFieldID, nObjectRight, pCondition);
		if	(pos == NULL)
		{
			sprintf(g_strMsg, "因为角色%s没有作用在%s.%s.%s上的%s权限,所以该回收语句执行失败!",
				strRoleName, m_strDBName, strTableName,
				pField->m_strFieldName, g_strObjectRight[nObjectRight]);
			g_msg.ThrowErrorMsg(g_strMsg);
			return	FALSE;
		}

		CSdbms_RoleObjectRight *pObjectRight = pRole->m_ORList.GetAt(pos);

		//如果bRstrict==TRUE,则判断是否该权限已经授予给其他用户了
		if	(bRestrict && (pObjectRight->m_ToRoleArray.GetSize() > 0))
		{
			sprintf(g_strMsg, "因为角色%s中的作用在%s.%s.%s上的%s权限已经授权给了其他用户,所以该回收语句不能执行!",
					strRoleName, m_strDBName, strTableName,
					pField->m_strFieldName, g_strObjectRight[nObjectRight]);
			g_msg.ThrowErrorMsg(g_strMsg);
			return	FALSE;
		}

		//如果被收回授权的角色的某个子角色有此对象权限,收回授权失败
		CSdbms_Role *pChild = pRole->m_pFirstChildRole;
		while	(pChild != NULL)
		{
//			if	(pChild->m_pParentRole->HaveObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight))
			if	(pChild->FindObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight, pCondition))
			{
				sprintf(g_strMsg, "因为角色%s的子角色%s有在%s.%s.%s上的%s权限,所以不能收回授权",
						strRoleName, pChild->m_strRoleName, m_strDBName, strTableName, 
						pField->m_strFieldName, g_strObjectRight[nObjectRight]);
				g_msg.ThrowErrorMsg(g_strMsg);				
				break;
			}
			else
				pChild = pChild->m_pNextBrotherRole;
		}
	
		if	(pChild != NULL)	//收回授权失败,进行下一个
			return	FALSE;

		//遍历授权者数组
		int i=0;
		ASSERT(pObjectRight->m_FromUserRoleArray.GetSize() > 0);
		while (i < pObjectRight->m_FromUserRoleArray.GetSize())
		{
			CSdbms_RoleUser *pRoleUser = pObjectRight->m_FromUserRoleArray[i];
			CSdbms_User *pFromUser = pRoleUser->m_pUser;
			CSdbms_Role *pFromRole = pRoleUser->m_pRole;

			if	(pFromUser != pUser)	//是否是该用户授权的
				i++;
			else
			{
				ASSERT(pFromRole != g_sdbms.GetDbsaRole());

				bSuccess = true;	//只要授权者是该用户,则一定回收权限成功

				CString strTemp1, strTemp2;

				if	((pFromRole == g_sdbms.GetDbaRole())	||	//DBA角色
					 (pFromRole == g_sdbms.GetSystemRole()))	//SYSTEM角色
				{
					//用户应该仍属于DBA或SYSTEM角色
					ASSERT(g_sdbms.FindRoleUser(pFromUser, pFromRole) == pRoleUser);

					//收回该权限
					VERIFY(pObjectRight->RemoveFromUserRoleArray(pRole, pRoleUser, bRevokeGrant));

					if	(!bRevokeGrant)
					{
						CSdbms_RoleObjectRight *pTemp = pFromRole->m_ORList.GetHead();
						ASSERT(pTemp);
						VERIFY(pTemp->RemoveToRoleArray(pRole));	//系统预定义角色都只有一个对象权限结点
					}

					strTemp1 = (pFromRole == g_sdbms.GetDbaRole()) ? "DBA身份" : "SYSTEM身份";
				}
				else	//数据库创建者角色或表创建者角色或自定义角色
				{
					//用户角色关系仍然应该存在
					ASSERT(FindRoleUser(pFromRole, pFromUser) != NULL);

					//回收权限
					VERIFY(pObjectRight->RemoveFromUserRoleArray(pRole, pRoleUser, bRevokeGrant));

					CSdbms_Role *pTBCreatorRole = pTable->m_pCreatorRole;
//					VERIFY(GetTBCreatorRole(pTable->m_nTableID, &pTBCreatorRole));
		
					if	(!bRevokeGrant)
					{
						CSdbms_RoleObjectRight *pTemp=NULL;

						if	((pFromRole == m_pCreatorRole) ||	//DB创建者角色
							 (pFromRole == pTBCreatorRole))		//TB创建者角色
						{
							pTemp = pFromRole->m_ORList.GetHead();//系统预定义角色都只有一个对象权限结点
						}
						else	//自定义角色
						{
							POSITION pos2 = pFromRole->FindObjectRight(nTableID, nFieldID, nObjectRight, pCondition);
							ASSERT(pos2);
							pTemp = pFromRole->m_ORList.GetAt(pos2);
						}
						ASSERT(pTemp);
						VERIFY(pTemp->RemoveToRoleArray(pRole));	
					}


					if	(pFromRole == m_pCreatorRole)	//数据库创建者角色
						strTemp1.Format("数据库%s创建者", m_strDBName);
					else if (pFromRole == pTBCreatorRole)	//表创建者角色
						strTemp1.Format("表%s创建者身份", strTableName);
					else	//自定义角色
						strTemp1.Format("%s身份", pFromRole->m_strRoleName);
				}

				sprintf(g_strMsg, "用户%s成功地以", pUser->m_strUserName);
		

⌨️ 快捷键说明

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