Het is vrij lastig uit te leggen, maar als jullie mee willen denken, dan heel graag natuurlijk.
Het gaat hoofdzakelijk om twee tabellen:
Tabel 1 voor opslag van alle objecten in de database
[code=sql]
CREATE TABLE `cms_objects` (
`cms_objectID` int(11) NOT NULL auto_increment,
`type` varchar(10) NOT NULL default '',
`parentID` int(11) NOT NULL default '0',
`lft` int(11) NOT NULL default '0',
`rgt` int(11) NOT NULL default '0',
`depth` int(11) NOT NULL default '0',
PRIMARY KEY (`cms_objectID`),
UNIQUE KEY `lft` (`lft`),
UNIQUE KEY `rgt` (`rgt`),
KEY `parentID` (`parentID`),
KEY `type` (`type`),
KEY `depth` (`depth`)
) TYPE=MyISAM
[/code=sql]
Tabel 2 voor rechten op de tabel, afhankelijk van de gebruiker of diens rol
SQL:
1
2
3
4
5
6
7
8
9
10
| CREATE TABLE `cms_objects2operations` (
`cms_objectID` int(11) NOT NULL default '0',
`auth_roleID` int(11) NOT NULL default '0',
`auth_userID` int(11) NOT NULL default '0',
`auth_operationID` int(11) NOT NULL default '0',
`value` int(2) NOT NULL default '0',
PRIMARY KEY (`cms_objectID`,`auth_roleID`,`auth_userID`,`auth_operationID`),
KEY `value` (`value`),
KEY `auth_operationID` (`auth_operationID`)
) TYPE=MyISAM; |
Hoofddoel is om - in één query - objecten uit de cms_objects tabel te kunnen halen die aan bepaalde voorwaarden voldoen EN waarvoor de gebruiker gerechtigd is.
- De rechten kunnen zijn ingesteld op het object zelf of op één van de nested-set-parents van het object.
- Wanneer er op verschillende parents rechten zijn ingesteld voor huidige gebruiker of één van diens rollen, dan moeten de rechten op de "diepste" nested node worden aangehouden. Voorts is het zo dat wanneer een gebruiker rechten toegekend/ontzegd heeft gekregen op zijn auth_userID zelf, dat die dan altijd prevaleren boven rechten op diens rol(len).
- Wanneer er geen rechten op de gebruiker zelf zijn, worden de rechten op één van zijn rollen aangehouden.
- Wanneer rol 1 van gebruiker rechten ontzegd, terwijl rol 2 van gebruiker rechten toekend, dan prevaleert het toekennen van de rechten, óók wanneer deze rechten op een "minder diepe" parent zijn ingesteld.
Ik heb nu een query die werkt ... maar die is te traag om toegepast te kunnen worden in een LIVE omgeving:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| SELECT
O.*
FROM
cms_objects AS O
WHERE
O.lft > 1 AND O.lft < 88578
AND O.type = 'message'
AND
(
SELECT
o2o.value
FROM
cms_objects2operations AS o2o, cms_objects as parents
WHERE
o2o.cms_objectID = parents.cms_objectID
AND parents.lft <= O.lft
AND parents.rgt >= O.lft
AND o2o.auth_operationID = 1
AND (
o2o.auth_userID = 11
OR o2o.auth_roleID IN (2, 3)
)
AND CONCAT_WS('#', o2o.auth_userID, o2o.auth_roleID, parents.depth) IN
(
SELECT
CONCAT_WS('#',
o2o2.auth_userID, o2o2.auth_roleID, max(parents2.depth)) AS str
FROM
cms_objects as parents2, cms_objects2operations AS o2o2
WHERE
o2o2.cms_objectID = parents2.cms_objectID
AND parents2.lft <= O.lft
AND parents2.rgt >= O.lft
AND o2o2.auth_operationID = 1
AND (
o2o2.auth_userID = 11
OR o2o2.auth_roleID IN (2,3)
)
GROUP BY auth_roleID, auth_userID
)
ORDER BY
o2o.auth_userID DESC, o2o.value DESC
LIMIT 0, 1
) = 1
ORDER BY O.lft
LIMIT 0, 50 |
Nog even de explain van de query erbij, voor zover dat enigszins te ontcijferen valt:
SQL:
1
2
3
4
5
6
| id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY O ref lft,type type 10 const 7204 Using where; Using filesort
2 DEPENDENT SUBQUERY o2o ref PRIMARY,auth_operationID auth_operationID 4 const 18 Using where; Using filesort
2 DEPENDENT SUBQUERY parents eq_ref PRIMARY,lft,rgt PRIMARY 4 sentimento.o2o.cms_objectID 1 Using where
3 DEPENDENT SUBQUERY o2o2 ref PRIMARY,auth_operationID auth_operationID 4 const 18 Using where; Using temporary; Using filesort
3 DEPENDENT SUBQUERY parents2 eq_ref PRIMARY,lft,rgt PRIMARY 4 sentimento.o2o2.cms_objectID 1 Using where |
[
Voor 10% gewijzigd door
gvanh op 07-08-2007 13:53
. Reden: explain toegevoegd. ]