Projet

Général

Profil

0002-sql-add-workflow_merged_roles_dict-jsonb-column-5888.patch

Frédéric Péters, 08 février 2022 09:56

Télécharger (9,26 ko)

Voir les différences:

Subject: [PATCH 2/3] sql: add workflow_merged_roles_dict jsonb column (#58881)

 tests/test_sql.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++
 wcs/formdata.py   | 17 ++++++++++++++
 wcs/sql.py        | 32 ++++++++++++++++++++-----
 3 files changed, 103 insertions(+), 6 deletions(-)
tests/test_sql.py
2073 2073
    assert sql.SqlUser.get(id=user2.id).is_active is True
2074 2074

  
2075 2075

  
2076
def test_migration_58_workflow_roles_dict(pub):
2077
    formdef = FormDef()
2078
    formdef.name = 'tests migration 58'
2079
    formdef.fields = []
2080
    formdef.workflow_roles = {'_receiver': '123'}
2081
    formdef.store()
2082

  
2083
    formdata = formdef.data_class()()
2084
    formdata.store()
2085

  
2086
    formdata = formdef.data_class()()
2087
    formdata.workflow_roles = {'_receiver': ['_user:123', '_user:456']}
2088
    formdata.store()
2089

  
2090
    conn, cur = sql.get_connection_and_cursor()
2091
    cur.execute('UPDATE wcs_meta SET value = 57 WHERE key = %s', ('sql_level',))
2092
    conn.commit()
2093
    cur.close()
2094

  
2095
    conn, cur = sql.get_connection_and_cursor()
2096
    cur.execute('ALTER TABLE %s DROP COLUMN workflow_merged_roles_dict' % formdef.table_name)
2097
    sql.migrate()
2098
    assert column_exists_in_table(cur, formdef.table_name, 'workflow_merged_roles_dict')
2099
    assert migration_level(cur) >= 58
2100
    assert sql.is_reindex_needed('formdata', conn=conn, cur=cur) is True
2101
    assert formdef.data_class().count([st.Null('workflow_merged_roles_dict')]) == 2
2102
    sql.reindex()
2103
    assert formdef.data_class().count([st.Null('workflow_merged_roles_dict')]) == 0
2104

  
2105

  
2106
def test_workflow_roles_dict_change(pub):
2107
    formdef = FormDef()
2108
    formdef.name = 'test_workflow_roles_dict_change'
2109
    formdef.fields = []
2110
    formdef.workflow_roles = {'_receiver': '123'}
2111
    formdef.store()
2112

  
2113
    formdata = formdef.data_class()()
2114
    formdata.workflow_roles = {'_receiver': ['_user:123', '_user:456']}
2115
    formdata.store()
2116

  
2117
    conn, cur = sql.get_connection_and_cursor()
2118
    cur.execute('SELECT workflow_merged_roles_dict FROM %s WHERE id = %s' % (formdef.table_name, formdata.id))
2119
    merged_roles_dict = cur.fetchone()[0]
2120
    assert merged_roles_dict == {'_receiver': ['123', '_user:123', '_user:456']}
2121
    conn.commit()
2122
    cur.close()
2123

  
2124
    formdef.workflow_roles = {'_receiver': '234'}
2125
    formdef.store()
2126
    formdef.data_class().rebuild_security()
2127

  
2128
    conn, cur = sql.get_connection_and_cursor()
2129
    cur.execute('SELECT workflow_merged_roles_dict FROM %s WHERE id = %s' % (formdef.table_name, formdata.id))
2130
    merged_roles_dict = cur.fetchone()[0]
2131
    assert merged_roles_dict == {'_receiver': ['234', '_user:123', '_user:456']}
2132
    conn.commit()
2133
    cur.close()
2134

  
2135

  
2076 2136
def test_logged_error_store_without_integrity_error(pub, sql_queries):
2077 2137
    sql.LoggedError.record('there was an error')
2078 2138

  
wcs/formdata.py
1098 1098
            status = self.status
1099 1099
        return status == 'draft'
1100 1100

  
1101
    @property
1102
    def workflow_merged_roles_dict(self):
1103
        merged_dict = {}
1104
        for k, v in (self.formdef.workflow_roles or {}).items():
1105
            merged_dict[k] = [v]
1106
        for k, v in (self.workflow_roles or {}).items():
1107
            if k not in merged_dict:
1108
                merged_dict[k] = []
1109
            merged_dict[k].extend(v)
1110
        return merged_dict
1111

  
1112
    @workflow_merged_roles_dict.setter
1113
    def workflow_merged_roles_dict(self, value):
1114
        # do not do anything, this setter is just there as the SQL retrieval will
1115
        # try to set the property.
1116
        pass
1117

  
1101 1118
    def get_concerned_roles(self):
1102 1119
        if self.is_draft():
1103 1120
            # drafts are only visible to submitter
wcs/sql.py
587 587
        'page_no',
588 588
        'anonymised',
589 589
        'workflow_roles',
590
        # workflow_merged_roles_dict combines workflow_roles from formdef and
591
        # formdata and is used to filter on function assignment.
592
        'workflow_merged_roles_dict',
590 593
        # workflow_roles_array is created from workflow_roles to be used in
591 594
        # get_ids_with_indexed_value
592 595
        'workflow_roles_array',
......
613 616
    if 'workflow_roles' not in existing_fields:
614 617
        cur.execute('''ALTER TABLE %s ADD COLUMN workflow_roles bytea''' % table_name)
615 618
        cur.execute('''ALTER TABLE %s ADD COLUMN workflow_roles_array text[]''' % table_name)
619
    if 'workflow_merged_roles_dict' not in existing_fields:
620
        cur.execute('''ALTER TABLE %s ADD COLUMN workflow_merged_roles_dict jsonb''' % table_name)
616 621
    if 'concerned_roles_array' not in existing_fields:
617 622
        cur.execute('''ALTER TABLE %s ADD COLUMN concerned_roles_array text[]''' % table_name)
618 623
    if 'actions_roles_array' not in existing_fields:
......
2019 2024
        ('prefilling_data', 'bytea'),
2020 2025
        ('id_display', 'varchar'),
2021 2026
        ('workflow_roles', 'bytea'),
2027
        ('workflow_merged_roles_dict', 'jsonb'),
2022 2028
        ('workflow_roles_array', 'text[]'),
2023 2029
        ('concerned_roles_array', 'text[]'),
2024 2030
        ('actions_roles_array', 'text[]'),
......
2158 2164
            'submission_agent_id': self.submission_agent_id,
2159 2165
            'submission_channel': self.submission_channel,
2160 2166
            'criticality_level': self.criticality_level,
2167
            'workflow_merged_roles_dict': self.workflow_merged_roles_dict,
2161 2168
        }
2162 2169
        if self.last_update_time:
2163 2170
            sql_dict['last_update_time'] = datetime.datetime.fromtimestamp(time.mktime(self.last_update_time))
......
2473 2480
        for formdata in formdatas:
2474 2481
            sql_statement = (
2475 2482
                '''UPDATE %s
2476
                                  SET concerned_roles_array = %%(roles)s,
2477
                                      actions_roles_array = %%(actions_roles)s
2478
                                WHERE id = %%(id)s'''
2483
                      SET concerned_roles_array = %%(roles)s,
2484
                          actions_roles_array = %%(actions_roles)s,
2485
                          workflow_merged_roles_dict = %%(workflow_merged_roles_dict)s
2486
                    WHERE id = %%(id)s'''
2479 2487
                % cls._table_name
2480 2488
            )
2481 2489
            with get_publisher().substitutions.temporary_feed(formdata):
......
2488 2496
                        'id': formdata.id,
2489 2497
                        'roles': [str(x) for x in formdata.concerned_roles if x],
2490 2498
                        'actions_roles': [str(x) for x in formdata.actions_roles if x],
2499
                        'workflow_merged_roles_dict': formdata.workflow_merged_roles_dict,
2491 2500
                    },
2492 2501
                )
2493 2502
        conn.commit()
......
3656 3665
# latest migration, number + description (description is not used
3657 3666
# programmaticaly but will make sure git conflicts if two migrations are
3658 3667
# separately added with the same number)
3659
SQL_LEVEL = (57, 'store tokens in SQL')
3668
SQL_LEVEL = (58, 'add workflow_merged_roles_dict')
3660 3669

  
3661 3670

  
3662 3671
def migrate_global_views(conn, cur):
......
3782 3791
        # 21: (second part), store ascii_name of users
3783 3792
        # 23: (first part), use misc.simplify() over full text queries
3784 3793
        set_reindex('user', 'needed', conn=conn, cur=cur)
3785
    if sql_level < 51:
3794
    if sql_level < 58:
3786 3795
        # 17: store last_update_time in tables
3787 3796
        # 18: add user name to full-text search index
3788 3797
        # 21: (third part), add user ascii_names to full-text index
......
3852 3861
        # 57: store tokens in SQL
3853 3862
        do_tokens_table()
3854 3863
        migrate_legacy_tokens()
3864
    if sql_level < 58:
3865
        # 58: add workflow_merged_roles_dict as a jsonb column with
3866
        #     combined formdef and formdata value.
3867
        from wcs.carddef import CardDef
3868
        from wcs.formdef import FormDef
3869

  
3870
        for formdef in FormDef.select() + CardDef.select():
3871
            do_formdef_tables(formdef, rebuild_views=False, rebuild_global_views=False)
3872
        migrate_views(conn, cur)
3873
        set_reindex('formdata', 'needed', conn=conn, cur=cur)
3855 3874

  
3856 3875
    cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', (str(SQL_LEVEL[0]), 'sql_level'))
3857 3876

  
......
3868 3887
            user.store()
3869 3888
        set_reindex('user', 'done', conn=conn, cur=cur)
3870 3889

  
3890
    from wcs.carddef import CardDef
3871 3891
    from wcs.formdef import FormDef
3872 3892

  
3873 3893
    if is_reindex_needed('formdata', conn=conn, cur=cur):
3874 3894
        # load and store all formdatas
3875
        for formdef in FormDef.select():
3895
        for formdef in FormDef.select() + CardDef.select():
3876 3896
            for formdata in formdef.data_class().select(iterator=True):
3877 3897
                try:
3878 3898
                    formdata.migrate()
3879
-