Projet

Général

Profil

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

Pierre Ducroquet, 20 juin 2022 12:56

Télécharger (3,91 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, 31 insertions(+), 11 deletions(-)
wcs/formdata.py
1111 1111
        return variables
1112 1112

  
1113 1113
    @classmethod
1114
    def rebuild_security(cls):
1114
    def rebuild_security(cls, must_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
2870 2870
        cur.close()
2871 2871

  
2872 2872
    @classmethod
2873
    def rebuild_security(cls):
2873
    def rebuild_security(cls, must_update=False):
2874 2874
        formdatas = cls.select(order_by='id', iterator=True)
2875 2875
        conn, cur = get_connection_and_cursor()
2876
        i = 0
2876 2877
        for formdata in formdatas:
2877
            sql_statement = (
2878
                '''UPDATE %s
2879
                      SET concerned_roles_array = %%(roles)s,
2880
                          actions_roles_array = %%(actions_roles)s,
2881
                          workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2882
                    WHERE id = %%(id)s'''
2883
                % cls._table_name
2884
            )
2878
            # don't update all formdata before commiting
2879
            # this will make us hold locks for much longer than required
2880
            i += 1
2881
            if i % 100 == 0:
2882
                conn.commit()
2883

  
2884
            if not must_update:
2885
                sql_statement = (
2886
                    '''UPDATE %s
2887
                          SET concerned_roles_array = %%(roles)s,
2888
                              actions_roles_array = %%(actions_roles)s,
2889
                              workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2890
                        WHERE id = %%(id)s
2891
                          AND (concerned_roles_array <> %%(roles)s OR
2892
                              actions_roles_array <> %%(actions_roles)s OR
2893
                              workflow_merged_roles_dict <> %%(workflow_merged_roles_dict)s)'''
2894
                    % cls._table_name
2895
                )
2896
            else:
2897
                sql_statement = (
2898
                    '''UPDATE %s
2899
                          SET concerned_roles_array = %%(roles)s,
2900
                              actions_roles_array = %%(actions_roles)s,
2901
                              workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2902
                        WHERE id = %%(id)s'''
2903
                    % cls._table_name
2904
                )
2885 2905
            with get_publisher().substitutions.temporary_feed(formdata):
2886 2906
                # formdata is already added to sources list in individual
2887 2907
                # {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
-