📄 sdbms_datastruct.cpp
字号:
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 + -