Projet

Général

Profil

0001-sql-rework-the-rebuild_security-function-66315.patch

Pierre Ducroquet, 29 juin 2022 14:32

Télécharger (3,92 ko)

Voir les différences:

Subject: [PATCH] sql: rework the rebuild_security function (#66315)

The function rewrote the whole table without checking if updates were really required.
Instead, we now check before updating, and we commit every 100 rows to prevent any
long lock
 wcs/formdata.py  |  2 +-
 wcs/sql.py       | 38 ++++++++++++++++++++++++++++----------
 wcs/workflows.py |  2 +-
 3 files changed, 30 insertions(+), 12 deletions(-)
wcs/formdata.py
1111 1111
        return variables
1112 1112

  
1113 1113
    @classmethod
1114
    def rebuild_security(cls):
1114
    def rebuild_security(cls, force_update=False):
1115 1115
        with get_publisher().substitutions.temporary_feed(cls._formdef):
1116 1116
            cls.rebuild_indexes(indexes=['concerned_roles', 'actions_roles'])
1117 1117

  
wcs/sql.py
2936 2936
        cur.close()
2937 2937

  
2938 2938
    @classmethod
2939
    def rebuild_security(cls):
2939
    def rebuild_security(cls, update_all=False):
2940 2940
        formdatas = cls.select(order_by='id', iterator=True)
2941 2941
        conn, cur = get_connection_and_cursor()
2942
        for formdata in formdatas:
2943
            sql_statement = (
2944
                '''UPDATE %s
2945
                      SET concerned_roles_array = %%(roles)s,
2946
                          actions_roles_array = %%(actions_roles)s,
2947
                          workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2948
                    WHERE id = %%(id)s'''
2949
                % cls._table_name
2950
            )
2942
        for i, formdata in enumerate(formdatas):
2943
            # don't update all formdata before commiting
2944
            # this will make us hold locks for much longer than required
2945
            if i % 100 == 0:
2946
                conn.commit()
2947

  
2948
            if not update_all:
2949
                sql_statement = (
2950
                    '''UPDATE %s
2951
                          SET concerned_roles_array = %%(roles)s,
2952
                              actions_roles_array = %%(actions_roles)s,
2953
                              workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2954
                        WHERE id = %%(id)s
2955
                          AND (concerned_roles_array <> %%(roles)s OR
2956
                              actions_roles_array <> %%(actions_roles)s OR
2957
                              workflow_merged_roles_dict <> %%(workflow_merged_roles_dict)s)'''
2958
                    % cls._table_name
2959
                )
2960
            else:
2961
                sql_statement = (
2962
                    '''UPDATE %s
2963
                          SET concerned_roles_array = %%(roles)s,
2964
                              actions_roles_array = %%(actions_roles)s,
2965
                              workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2966
                        WHERE id = %%(id)s'''
2967
                    % cls._table_name
2968
                )
2951 2969
            with get_publisher().substitutions.temporary_feed(formdata):
2952 2970
                # formdata is already added to sources list in individual
2953 2971
                # {concerned,actions}_roles but adding it first here will
wcs/workflows.py
615 615
                        formdef.geolocations = {'base': str(_('Geolocation'))}
616 616
                        formdef.store(comment=_('Geolocation enabled by workflow'))
617 617
                    formdef.update_storage()
618
                formdef.data_class().rebuild_security()
618
                formdef.data_class().rebuild_security(must_update)
619 619

  
620 620
        if not migration_update:
621 621
            if get_response():
622
-