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

📄 sdbms_datastruct.cpp

📁 使用yacc的一个例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

/**********************************************************************
功能:释放内存
***********************************************************************/
CSdbms_Database::~CSdbms_Database()
{
	if	(m_bInit)	//要求必须显示调用SaveDD函数
		SaveDD();

//	if	(m_pGuestRole)
//		delete m_pGuestRole;

//	if	(m_pOwnerRole)
//		delete m_pOwnerRole;

	ASSERT(m_pRole);
	delete m_pRole;

//	ASSERT(m_pCreatorRole);
//	delete m_pCreatorRole;

	POSITION pos = m_RoleUserList.GetHeadPosition();
	while (pos != NULL)
	{
		delete m_RoleUserList.GetNext(pos);
	}
	m_RoleUserList.RemoveAll();

	for	(int i=0; i<m_TableArray.GetSize(); i++)
	{
		delete m_TableArray[i];
	}
	m_TableArray.RemoveAll();

	pos = m_UserTableList.GetHeadPosition();
	while (pos != NULL)
	{
		delete m_UserTableList.GetNext(pos);
	}
	m_UserTableList.RemoveAll();
}


/**********************************************************************
功能:根据角色名找到自定义角色的指针
算法:非递归先序搜索角色树
***********************************************************************/
BOOL CSdbms_Database::GetRole(CString strRoleName, CSdbms_Role **ppRole)
{
	ASSERT(m_bInit && m_pRole);	//DB必须已经初始化了
	ASSERT(strRoleName.CompareNoCase(SYSTEM_ROLE_SYSTEM) != 0);	//不能使用系统定义的角色名
	ASSERT(strRoleName.CompareNoCase(SYSTEM_ROLE_DBSA) != 0);
	ASSERT(strRoleName.CompareNoCase(SYSTEM_ROLE_DBA) != 0);
	ASSERT(strRoleName.CompareNoCase(SYSTEM_ROLE_LOGIN) != 0);
	ASSERT(strRoleName.CompareNoCase(SYSTEM_ROLE_GUEST) != 0);
	ASSERT(strRoleName.CompareNoCase(SYSTEM_ROLE_OWNER) != 0);

	CSdbms_Role *pStack[100];		//栈大小设为100
	CSdbms_Role *pTop;			//栈顶元素,=pStack[pTop]
	int	nTop = 0;			//栈顶指针

	pStack[nTop] = m_pRole;
	while	(nTop < 100)	//当栈没溢出
	{
		pTop = pStack[nTop];
		if	(pTop == NULL)	//退栈操作
		{
			if	(nTop == 0)
				break;
			else
			{
				nTop--;
				pStack[nTop] = pStack[nTop]->m_pFirstChildRole;	//压入右结点
			}
		}
		else if	(strRoleName.CompareNoCase(pTop->m_strRoleName) == 0)	//比较
		{
			*ppRole = pTop;
			return	TRUE;
		}
		else	
		{
			nTop++;
			pStack[nTop] = pTop->m_pNextBrotherRole;	//压入左结点
		}
	}

	*ppRole = NULL;

	if	(nTop >= 100)
		g_msg.ThrowErrorMsg("栈溢出");

	return	FALSE;
}


/**********************************************************************
功能:根据角色内码找到自定义角色的指针
算法:非递归先序搜索角色树
***********************************************************************/
BOOL CSdbms_Database::GetRole(UINT nRoleID, CSdbms_Role **ppRole)
{
	ASSERT(m_bInit && m_pRole);	//DB必须已经初始化了
//	ASSERT(nRoleID != ROLE_LOGIN);	//不能使用系统定义的角色名

	CSdbms_Role *pStack[100];		//栈大小设为100
	CSdbms_Role *pTop;			//栈顶元素,=pStack[pTop]
	int	nTop = 0;			//栈顶指针

	pStack[nTop] = m_pRole;
	while	(nTop < 100)	//当栈没溢出
	{
		pTop = pStack[nTop];
		if	(pTop == NULL)	//退栈操作
		{
			if	(nTop == 0)
				break;
			else
			{
				nTop--;
				pStack[nTop] = pStack[nTop]->m_pFirstChildRole;	//压入右结点
			}
		}
		else if	(nRoleID == pTop->m_nRoleID)	//比较
		{
			*ppRole = pTop;
			return	TRUE;
		}
		else	
		{
			nTop++;
			pStack[nTop] = pTop->m_pNextBrotherRole;	//压入左结点
		}
	}

	*ppRole = NULL;

	if	(nTop >= 100)
		g_msg.ThrowErrorMsg("栈溢出");

	return	FALSE;
}

/**********************************************************************
功能:根据关系名找到数据库中的表指针
算法:顺序遍历表链表,若表较多的话可考虑使用映射表
***********************************************************************/
BOOL CSdbms_Database::GetTable(CString strTableName, CSdbms_Table **ppTable)
{
	ASSERT(!strTableName.IsEmpty());

	for	(int i=0; i<m_TableArray.GetSize(); i++)
	{
		CSdbms_Table *pTemp = m_TableArray[i];
		if	(strTableName.CompareNoCase(pTemp->m_strTableName) == 0)
		{
			*ppTable = pTemp;
			return	TRUE;
		}
	}
		
	return	FALSE;
}

/**********************************************************************
功能:计算用户在该表上的当前安全级
***********************************************************************/
CSdbms_SecurityLevel CSdbms_Database::GetUserCurSecLevel(CSdbms_User *pUser, CSdbms_Table *pTable)
{
	CSdbms_SecurityLevel slUser;
	POSITION pos;
	if	((pos = FindUserTable(pUser, pTable)) != NULL)	//先查找用户-关系表
	{
		//用户当前安全级<=用户允许安全级<=表安全级
		CSdbms_UserTable *pUserTable = m_UserTableList.GetAt(pos);
		ASSERT(!(pUserTable->m_CurSecLevel.IsEmpty()));
		ASSERT(pUserTable->m_CurSecLevel <= pUserTable->m_AllowSecLevel);
		ASSERT(pUserTable->m_AllowSecLevel <= pTable->m_SecLevel);
		slUser = pUserTable->m_CurSecLevel;
	}
	else if	(IsTableGuest(pUser, pTable))
	{
		//如果没找到,则密级等于用户密级与表密级的最小值,非分层范围等于表安全级的非分层范围
		slUser = pTable->m_SecLevel;
		slUser.m_nClassifaction = min(pUser->m_SecLevel.m_nClassifaction, pTable->m_SecLevel.m_nClassifaction);
	}
	else
	{
		//slUser.Empty();
	}

	return	slUser;
}

/**********************************************************************
功能:计算用户在该表上的允许安全级
***********************************************************************/
CSdbms_SecurityLevel CSdbms_Database::GetUserAllowSecLevel(CSdbms_User *pUser, CSdbms_Table *pTable)
{
	CSdbms_SecurityLevel slUser;
	POSITION pos;
	if	((pos = FindUserTable(pUser, pTable)) != NULL)	//先查找用户-关系表
	{
		//用户当前安全级<=用户允许安全级<=表安全级
		CSdbms_UserTable *pUserTable = m_UserTableList.GetAt(pos);
		ASSERT(pUserTable->m_CurSecLevel <= pUserTable->m_AllowSecLevel);
		ASSERT(pUserTable->m_AllowSecLevel <= pTable->m_SecLevel);
		slUser = pUserTable->m_AllowSecLevel;
	}
	else if	(IsTableGuest(pUser, pTable))
	{
		//如果没找到,则缺省的允许安全级的密级=min(表安全级密级,用户密级),非分层范围等于表安全级的非分层范围
		slUser = pTable->m_SecLevel;
		slUser.m_nClassifaction = min(pUser->m_SecLevel.m_nClassifaction, pTable->m_SecLevel.m_nClassifaction);
	}
	else
	{
		//slUser.Empty();
	}

	return	slUser;
}

/**********************************************************************
功能:根据关系内码找到数据库中的表指针
算法:顺序遍历表链表,若表较多的话可考虑使用映射表
***********************************************************************/
BOOL CSdbms_Database::GetTable(UINT nTableID, CSdbms_Table **ppTable)
{
	ASSERT(nTableID >= 0);

	for	(int i=0; i<m_TableArray.GetSize(); i++)
	{
		CSdbms_Table *pTemp = m_TableArray[i];
		if	(pTemp->m_nTableID == nTableID)
		{
			*ppTable = pTemp;
			return	TRUE;
		}
		else if	(pTemp->m_nTableID > nTableID)
			break;
	}
	
	return	FALSE;
}

/**********************************************************************
功能:判断用户是否可连接到数据库上
算法:首先判断用户是否属于某自定义角色,再判断是否属于某表内的角色
***********************************************************************/
BOOL CSdbms_Database::IsOwnLoginRole(CSdbms_User *pUser)
{
	ASSERT(m_bInit);			//DB必须已经初始化了
	ASSERT(pUser);
	
	//判断用户是否属于某个角色
	if	(pUser->m_pos != NULL)
		return TRUE;

	return	FALSE;
}


/**********************************************************************
功能:判断用户是否是数据库的创建者
***********************************************************************/
BOOL CSdbms_Database::IsDBCreator(UINT nUserID)
{
	ASSERT(m_bInit);			//DB必须已经初始化了
		
	return	(m_nCreatorID == nUserID);
}

/**********************************************************************
功能:判断用户是否是数据库中某表的创建者
***********************************************************************/
BOOL CSdbms_Database::IsTableCreator(UINT nUserID, CString strTableName)
{
	//表是否存在
	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);

	return	pTable->IsTableCreator(nUserID);
}

/**********************************************************************
功能:判断用户是否是表上的客户
***********************************************************************/
BOOL CSdbms_Database::IsTableGuest(CSdbms_User *pUser, CSdbms_Table *pTable)
{
	ASSERT(pUser && pTable);
	
	UINT nUserID = pUser->m_nUserID;
	UINT nTableID = pTable->m_nTableID;

	if	(IsDBCreator(nUserID))	//数据库创建者
		return	TRUE;

	if	(pTable->IsTableCreator(nUserID))	//表创建者
		return	TRUE;

	if	(g_sdbms.IsOwnDbaRole(nUserID))	//DBA用户
		return	TRUE;

	//遍历用户所属的自定义角色
	POSITION pos = pUser->m_pos;
	while (pos)
	{
		CSdbms_RoleUser *pRoleUser = m_UserRoleList.GetNext(pos);
		if	(pRoleUser->m_pUser->m_nUserID != nUserID)
			break;

		CSdbms_Role *pRole = pRoleUser->m_pRole;
		POSITION pos2 = pRole->m_ORList.GetHeadPosition();
		while (pos2)	//遍历角色所有的对象权限
		{
			CSdbms_RoleObjectRight *pRight = pRole->m_ORList.GetNext(pos2);
			if	(pRight->m_nTableID == nTableID)
				return	TRUE;
		}
	}

	return	FALSE;
}

/**********************************************************************
功能:用户在这个数据库上是否具有某些系统权限
***********************************************************************/
BOOL CSdbms_Database::HaveSystemRight(CSdbms_User *pUser, SystemRight nSqlID)
{
	ASSERT(pUser);

	POSITION pos = pUser->m_pos;
	while (pos != NULL)
	{
		CSdbms_RoleUser *pRoleUser = m_UserRoleList.GetNext(pos);
		if	(pRoleUser->m_pUser->m_nUserID != pUser->m_nUserID)
			break;
		else if	(pRoleUser->m_pRole->FindSystemRight(nSqlID))
			return	TRUE;
	}

	return	FALSE;
}

/**********************************************************************
功能:用户在某个表的某个列上是否具有操作权限
算法:遍历用户所属的角色,查找是否具有指定权限(不管对象权限中有无与列相关的谓词条件)
***********************************************************************/
BOOL CSdbms_Database::FindObjectRight(CSdbms_User *pUser, CSdbms_Table *pTable, CSdbms_Field *pField, ObjectRight nObjectRight)
{
	ASSERT(pUser && pTable && pField);

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

	if	(g_sdbms.IsOwnDbaRole(pUser->m_nUserID)	||	//DBA
		 IsDBCreator(pUser->m_nUserID)			||	//数据库创建者
		 pTable->IsTableCreator(pUser->m_nUserID))	//表创建者
		return	TRUE;

	//遍历用户所属角色
	POSITION pos = pUser->m_pos;
	while (pos != NULL)
	{
		CSdbms_RoleUser *pRoleUser = m_UserRoleList.GetNext(pos);
		if	(pRoleUser->m_pUser->m_nUserID == pUser->m_nUserID)
		{
			//遍历角色所拥有的角色-对象权限表
			CSdbms_Role *pRole = pRoleUser->m_pRole;
			if	(pRole->FindObjectRight(nTableID, nFieldID, nObjectRight))
				return	TRUE;
		}
		else
			break;
	}

	sprintf(g_strMsg, "用户%s没有在数据对象%s.%s.%s上的%s权限", 
		pUser->m_strUserName, m_strDBName, pTable->m_strTableName, pField->m_strFieldName, g_strObjectRight[nObjectRight]);
	g_msg.ThrowErrorMsg(g_strMsg);
	return	FALSE;
}

/**********************************************************************
功能:用户在某个表的某个列上是否具有操作权限(要计算与数值相关的谓词条件)
算法:遍历用户所属的角色,检查是否具有指定权限
***********************************************************************/
BOOL CSdbms_Database::HaveObjectRight(CSdbms_User *pUser, CSdbms_Table *pTable, 
					CSdbms_Field *pField, ObjectRight nObjectRight, BYTE *pRecord)
{
	ASSERT(pUser && pTable && pField);

	if	(g_sdbms.IsOwnDbaRole(pUser->m_nUserID)	||	//DBA
		 IsDBCreator(pUser->m_nUserID)			||	//数据库创建者
		 pTable->IsTableCreator(pUser->m_nUserID))	//表创建者
		return	TRUE;

	//遍历用户所属角色
	POSITION pos = pUser->m_pos;
	while (pos != NULL)
	{
		CSdbms_RoleUser *pRoleUser = m_UserRoleList.GetNext(pos);
		if	(pRoleUser->m_pUser->m_nUserID == pUser->m_nUserID)
		{
			//遍历角色所拥有的角色-对象权限表
			CSdbms_Role *pRole = pRoleUser->m_pRole;
			if	(pRole->HaveObjectRight(pTable, pField, nObjectRight, pRecord))
				return	TRUE;
		}
		else
			break;
	}

⌨️ 快捷键说明

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