Browse Source

improve group / rights query performance

Damien Accorsi 10 years ago
parent
commit
75ec2e1f61

+ 2 - 2
pboard/pboard/controllers/root.py View File

@@ -147,8 +147,8 @@ class RootController(BaseController):
147 147
             current_node=loCurrentNode,
148 148
             node_status_list = loNodeStatusList,
149 149
             keywords = highlight,
150
-            user_specific_groups = pld.PODStaticController.getUserSpecificGroups(),
151
-            real_groups = pld.PODStaticController.getRealGroups()
150
+            user_specific_group_rights = pld.PODStaticController.getUserDedicatedGroupRightsOnNode(node_id),
151
+            real_group_rights = pld.PODStaticController.getRealGroupRightsOnNode(node_id)
152 152
         )
153 153
 
154 154
     @expose('pboard.templates.search')

+ 47 - 4
pboard/pboard/lib/dbapi.py View File

@@ -52,12 +52,28 @@ class PODStaticController(object):
52 52
     return loGroups
53 53
 
54 54
   @classmethod
55
-  def getUserSpecificGroups(cls):
56
-    return DBSession.query(pbma.Group).filter(pbma.Group.personnal_group==True).all()
55
+  def getRealGroupRightsOnNode(cls, piNodeId: int) -> pbmd.DIRTY_GroupRightsOnNode:
56
+
57
+    groupRightsOnNodeCustomSelect = DBSession\
58
+        .query(pbmd.DIRTY_GroupRightsOnNode)\
59
+        .from_statement(pbmd.DIRTY_RealGroupRightOnNodeSqlQuery)\
60
+        .params(node_id=piNodeId)\
61
+        .all()
62
+
63
+    return groupRightsOnNodeCustomSelect
57 64
 
58 65
   @classmethod
59
-  def getRealGroups(cls):
60
-    return DBSession.query(pbma.Group).filter(pbma.Group.personnal_group==False).all()
66
+  def getUserDedicatedGroupRightsOnNode(cls, piNodeId: int) -> pbmd.DIRTY_GroupRightsOnNode:
67
+
68
+    groupRightsOnNodeCustomSelect = DBSession\
69
+        .query(pbmd.DIRTY_GroupRightsOnNode)\
70
+        .from_statement(pbmd.DIRTY_UserDedicatedGroupRightOnNodeSqlQuery)\
71
+        .params(node_id=piNodeId)\
72
+        .all()
73
+
74
+    return groupRightsOnNodeCustomSelect
75
+
76
+
61 77
 
62 78
 class PODUserFilteredApiController(object):
63 79
   
@@ -93,11 +109,38 @@ class PODUserFilteredApiController(object):
93 109
 
94 110
 
95 111
   def getNode(self, liNodeId):
112
+    """
96 113
     liOwnerIdList = self._getUserIdListForFiltering()
97 114
     if liNodeId!=0:
98 115
       return DBSession.query(pbmd.PBNode).options(joinedload_all("_lAllChildren")).filter(pbmd.PBNode.node_id==liNodeId).filter(pbmd.PBNode.owner_id.in_(liOwnerIdList)).one()
99 116
     return None
117
+    """
100 118
 
119
+    sqla.or_
120
+    lsSqlSelectQuery = """pod_nodes.node_id IN
121
+(SELECT
122
+	pgn.node_id
123
+FROM
124
+	pod_group_node AS pgn
125
+	join pod_user_group AS pug ON pug.group_id = pgn.group_id
126
+	join pod_user AS pu ON pug.user_id = pu.user_id
127
+WHERE
128
+	rights > 0
129
+	AND pu.user_id = %s)
130
+"""
131
+    lsNodeIdFiltering = lsSqlSelectQuery % (str(self._iCurrentUserId))
132
+    print("filter: ====>>>", lsNodeIdFiltering)
133
+    if liNodeId!=0:
134
+      return DBSession.query(pbmd.PBNode).options(joinedload_all("_lAllChildren"))\
135
+        .filter(pbmd.PBNode.node_id==liNodeId)\
136
+        .filter(
137
+          sqla.or_(
138
+            pbmd.PBNode.owner_id==self._iCurrentUserId,
139
+            lsNodeIdFiltering
140
+          )
141
+        )\
142
+        .one()
143
+    return None
101 144
 
102 145
   def getLastModifiedNodes(self, piMaxNodeNb):
103 146
     """

+ 75 - 0
pboard/pboard/model/data.py View File

@@ -8,11 +8,14 @@ from hashlib import sha256
8 8
 
9 9
 import bs4
10 10
 from sqlalchemy import Table, ForeignKey, Column, Sequence
11
+import sqlalchemy as sqla
12
+from sqlalchemy.sql.sqltypes import Boolean
11 13
 from sqlalchemy.types import Unicode, Integer, DateTime, Text, LargeBinary
12 14
 import sqlalchemy.types as sqlat
13 15
 from sqlalchemy.orm import relation, synonym, relationship
14 16
 from sqlalchemy.orm import backref
15 17
 import sqlalchemy.orm as sqlao
18
+import sqlalchemy.orm.query as sqlaoq
16 19
 from sqlalchemy import orm as sqlao
17 20
 
18 21
 from tg.i18n import ugettext as _, lazy_ugettext as l_
@@ -399,3 +402,75 @@ class PBNode(DeclarativeBase):
399 402
   def getHistory(self):
400 403
       return DBSession.execute("select node_id, version_id, created_at from pod_nodes_history where node_id = :node_id order by created_at desc", {"node_id":self.node_id}).fetchall()
401 404
 
405
+
406
+#####
407
+#
408
+# HACK - 2014-05-21 - D.A
409
+#
410
+# The following hack is a horrible piece of code that allow to map a raw SQL select to a mapped class
411
+#
412
+class DIRTY_GroupRightsOnNode(object):
413
+    def hasSomeAccess(self):
414
+        return self.rights >= pma.Rights.READ_ACCESS
415
+
416
+    def hasReadAccess(self):
417
+        return self.rights & pma.Rights.READ_ACCESS
418
+
419
+    def hasWriteAccess(self):
420
+        return self.rights & pma.Rights.WRITE_ACCESS
421
+
422
+DIRTY_group_rights_on_node_query = Table('fake_table', metadata,
423
+    Column('group_id', Integer, primary_key=True),
424
+    Column('node_id', Integer, primary_key=True),
425
+
426
+    Column('display_name', Unicode(255)),
427
+    Column('personnal_group', Boolean),
428
+    Column('rights', Integer, primary_key=True)
429
+)
430
+
431
+DIRTY_UserDedicatedGroupRightOnNodeSqlQuery = """
432
+SELECT
433
+    COALESCE(NULLIF(pg.display_name, ''), pu.display_name) AS display_name,
434
+    pg.personnal_group,
435
+    pg.group_id,
436
+    :node_id AS node_id,
437
+    COALESCE(pgn.rights, 0) AS rights
438
+FROM
439
+    pod_group AS pg
440
+    LEFT JOIN
441
+        pod_group_node AS pgn
442
+    ON
443
+        pg.group_id=pgn.group_id
444
+        AND pgn.node_id=:node_id
445
+    LEFT JOIN
446
+        pod_user AS pu
447
+    ON
448
+        pu.user_id=-pg.group_id
449
+WHERE
450
+    pg.personnal_group='t'
451
+ORDER BY
452
+    display_name
453
+;"""
454
+
455
+DIRTY_RealGroupRightOnNodeSqlQuery = """
456
+SELECT
457
+    pg.display_name AS display_name,
458
+    pg.personnal_group,
459
+    pg.group_id,
460
+    :node_id AS node_id,
461
+    COALESCE(pgn.rights, 0) AS rights
462
+FROM
463
+    pod_group AS pg
464
+    LEFT JOIN
465
+        pod_group_node AS pgn
466
+    ON
467
+        pg.group_id=pgn.group_id
468
+        AND pgn.node_id=:node_id
469
+WHERE
470
+    pg.personnal_group!='t'
471
+ORDER BY
472
+    display_name
473
+;"""
474
+
475
+sqlao.mapper(DIRTY_GroupRightsOnNode, DIRTY_group_rights_on_node_query)
476
+

+ 39 - 48
pboard/pboard/templates/document-widgets-tabs.mak View File

@@ -33,21 +33,17 @@
33 33
           <th></th>
34 34
         </tr>
35 35
       </thead>
36
-      % for loCurrentGroup in real_groups:
37
-        % if loCurrentGroup.hasSomeAccess(poNode):
36
+      % for loGroupRightsOnNode in real_group_rights:
37
+        % if loGroupRightsOnNode.hasSomeAccess():
38 38
           <tr>
39
-            <td>${loCurrentGroup.getDisplayName()}</td>
39
+            <td>${loGroupRightsOnNode.display_name}</td>
40 40
             <td>
41
-              % for loRight in loCurrentGroup.rights:
42
-                % if loRight.node_id==poNode.node_id:
43
-                  % if loRight.hasReadAccess():
44
-                    <span class="label label-success">R</span>
45
-                  % endif
46
-                  % if loRight.hasWriteAccess():
47
-                    <span class="label label-warning">W</span>
48
-                  % endif
49
-                % endif
50
-              % endfor
41
+              % if loGroupRightsOnNode.hasReadAccess():
42
+                <span class="label label-success">R</span>
43
+              % endif
44
+              % if loGroupRightsOnNode.hasWriteAccess():
45
+                <span class="label label-warning">W</span>
46
+              % endif
51 47
             </td>
52 48
           </tr>
53 49
         % endif
@@ -58,21 +54,17 @@
58 54
           <th></th>
59 55
         </tr>
60 56
       </thead>
61
-      % for loCurrentGroup in user_specific_groups:
62
-        % if loCurrentGroup.hasSomeAccess(poNode):
57
+      % for loGroupRightsOnNode in user_specific_group_rights:
58
+        % if loGroupRightsOnNode.hasSomeAccess():
63 59
           <tr>
64
-            <td>${loCurrentGroup.getDisplayName()}</td>
60
+            <td>${loGroupRightsOnNode.display_name}</td>
65 61
             <td>
66
-              % for loRight in loCurrentGroup.rights:
67
-                % if loRight.node_id==poNode.node_id:
68
-                  % if loRight.hasReadAccess():
69
-                    <span class="label label-success">R</span>
70
-                  % endif
71
-                  % if loRight.hasWriteAccess():
72
-                    <span class="label label-warning">W</span>
73
-                  % endif
74
-                % endif
75
-              % endfor
62
+              % if loGroupRightsOnNode.hasReadAccess():
63
+                <span class="label label-success">R</span>
64
+              % endif
65
+              % if loGroupRightsOnNode.hasWriteAccess():
66
+                <span class="label label-warning">W</span>
67
+              % endif
76 68
             </td>
77 69
           </tr>
78 70
         % endif
@@ -178,22 +170,23 @@
178 170
                   <th>${_('Access')}</th>
179 171
                 </tr>
180 172
               </thead>
181
-              % for loCurrentGroup in real_groups:
182
-              <tr id='user-${loCurrentGroup.group_id}-rights-row'>
173
+              % for loGroupRightsOnNode in real_group_rights:
174
+
175
+              <tr id='user-${loGroupRightsOnNode.group_id}-rights-row'>
183 176
                 <td>
184 177
                   <a
185 178
                     class="btn btn-mini"
186
-                    onclick="updateRights(${loCurrentGroup.group_id})"
179
+                    onclick="updateRights(${loGroupRightsOnNode.group_id})"
187 180
                   >
188 181
                     <i class="fa fa-key"></i>
189 182
                   </a>
190 183
                 </td>
191 184
                 <td class='pod-highlightable-access-management-cell'>
192
-                  ${loCurrentGroup.getDisplayName()}
193
-                  <input type="hidden" id="user-${loCurrentGroup.group_id}-value-read" name="read" value="" />
194
-                  <input type="hidden" id="user-${loCurrentGroup.group_id}-value-write" name="write" value="" />
185
+                  ${loGroupRightsOnNode.display_name}
186
+                  <input type="hidden" id="user-${loGroupRightsOnNode.group_id}-value-read" name="read" value="" />
187
+                  <input type="hidden" id="user-${loGroupRightsOnNode.group_id}-value-write" name="write" value="" />
195 188
                 </td>
196
-                <td id="user-${loCurrentGroup.group_id}-rights" class="pod-right-cell"></td>
189
+                <td id="user-${loGroupRightsOnNode.group_id}-rights" class="pod-right-cell"></td>
197 190
               </tr>
198 191
               % endfor
199 192
               
@@ -208,23 +201,23 @@
208 201
                   <th>${_('Access')}</th>
209 202
                 </tr>
210 203
               </thead>
211
-              % for loCurrentGroup in user_specific_groups:
204
+              % for loGroupRightsOnNode in user_specific_group_rights:
212 205
               
213
-              <tr id='user-${loCurrentGroup.group_id}-rights-row'>
206
+              <tr id='user-${loGroupRightsOnNode.group_id}-rights-row'>
214 207
                 <td>
215 208
                   <a
216 209
                     class="btn btn-mini"
217
-                    onclick="updateRights(${loCurrentGroup.group_id})"
210
+                    onclick="updateRights(${loGroupRightsOnNode.group_id})"
218 211
                   >
219 212
                     <i class="fa fa-key"></i>
220 213
                   </a>
221 214
                 </td>
222 215
                 <td class='pod-highlightable-access-management-cell'>
223
-                  ${loCurrentGroup.getDisplayName()}
224
-                  <input type="hidden" id="user-${loCurrentGroup.group_id}-value-read" name="read" value="" />
225
-                  <input type="hidden" id="user-${loCurrentGroup.group_id}-value-write" name="write" value="" />
216
+                  ${loGroupRightsOnNode.display_name}
217
+                  <input type="hidden" id="user-${loGroupRightsOnNode.group_id}-value-read" name="read" value="" />
218
+                  <input type="hidden" id="user-${loGroupRightsOnNode.group_id}-value-write" name="write" value="" />
226 219
                 </td>
227
-                <td id="user-${loCurrentGroup.group_id}-rights" class="pod-right-cell"></td>
220
+                <td id="user-${loGroupRightsOnNode.group_id}-rights" class="pod-right-cell"></td>
228 221
               </tr>
229 222
               % endfor
230 223
             </table>
@@ -348,18 +341,16 @@
348 341
 ## for read/write access management
349 342
 ##
350 343
 
351
-      % for loCurrentGroup in real_groups + user_specific_groups:
352
-        % if loCurrentGroup.hasSomeAccess(poNode)==False:
353
-              updateRights(${loCurrentGroup.group_id}, 0);
344
+## FIXME      % for loGroupRightsOnNode in real_group_rights:
345
+##      % for loCurrentGroup in real_group_rights + user_specific_group_rights:
346
+      % for loGroupRightsOnNode in real_group_rights + user_specific_group_rights:
347
+        % if loGroupRightsOnNode.hasSomeAccess()==False:
348
+          updateRights(${loGroupRightsOnNode.group_id}, 0);
354 349
         % else:
355
-          % for loRight in loCurrentGroup.rights:
356
-            % if loRight.node_id==poNode.node_id:
357 350
 ##
358 351
 ## The following line should build some javascript code similar to this:
359 352
 ## updateRights(-5, 3);
360
-              updateRights(${loCurrentGroup.group_id}, ${loRight.rights});
361
-            % endif
362
-          % endfor
353
+          updateRights(${loGroupRightsOnNode.group_id}, ${loGroupRightsOnNode.rights});
363 354
         % endif
364 355
       % endfor
365 356