Projet

Général

Profil

0003-sql-give-global-wcs_all_forms-table-creation-its-own.patch

Frédéric Péters, 25 mars 2022 14:53

Télécharger (8,2 ko)

Voir les différences:

Subject: [PATCH 3/9] sql: give global wcs_all_forms table creation its own
 function (#60552)

 wcs/sql.py | 168 ++++++++++++++++++++++++++---------------------------
 1 file changed, 84 insertions(+), 84 deletions(-)
wcs/sql.py
1733 1733
        )
1734 1734

  
1735 1735

  
1736
def init_global_table(conn, cur):
1737
    from .carddef import CardDef
1738
    from .formdef import FormDef
1739

  
1740
    cur.execute("SELECT relkind FROM pg_class WHERE relname = 'wcs_all_forms';")
1741
    rows = cur.fetchall()
1742
    if len(rows) != 0:
1743
        if rows[0][0] == 'v':
1744
            # force wcs_all_forms table creation
1745
            cur.execute('DROP VIEW IF EXISTS wcs_all_forms CASCADE;')
1746
            do_global_views(conn, cur)
1747
        else:
1748
            assert rows[0][0] == 'r'
1749
    else:
1750
        do_global_views(conn, cur)
1751

  
1752
    # now copy all data into the table
1753
    for formdef in FormDef.select() + CardDef.select():
1754
        category_value = formdef.category_id
1755
        if formdef.category_id is None:
1756
            category_value = "NULL"
1757
        geoloc_base_x_query = "NULL"
1758
        geoloc_base_y_query = "NULL"
1759
        if formdef.geolocations and 'base' in formdef.geolocations:
1760
            # default geolocation is in the 'base' key; we have to unstructure the
1761
            # field is the POINT type of postgresql cannot be used directly as it
1762
            # doesn't have an equality operator.
1763
            geoloc_base_x_query = "geoloc_base[0]"
1764
            geoloc_base_y_query = "geoloc_base[1]"
1765
        criticality_levels = len(formdef.workflow.criticality_levels or [0])
1766
        endpoint_status = formdef.workflow.get_endpoint_status()
1767
        endpoint_status_filter = ", ".join(["'wf-%s'" % x.id for x in endpoint_status])
1768
        if endpoint_status_filter == "":
1769
            # not the prettiest in town, but will do fine for now.
1770
            endpoint_status_filter = "'xxxx'"
1771
        object_type = formdef.data_sql_prefix  # shortcut.
1772
        formed_name_quotedstring = psycopg2.extensions.QuotedString(formdef.name)
1773
        formed_name_quotedstring.encoding = 'utf8'
1774
        formdef_name = formed_name_quotedstring.getquoted().decode()
1775
        cur.execute(
1776
            """
1777
            INSERT INTO wcs_all_forms
1778
            SELECT
1779
                {category_id},
1780
                '{object_type}',
1781
                {formdef_id},
1782
                id,
1783
                user_id,
1784
                receipt_time,
1785
                status,
1786
                id_display,
1787
                submission_agent_id,
1788
                submission_channel,
1789
                backoffice_submission,
1790
                last_update_time,
1791
                digests,
1792
                user_label,
1793
                concerned_roles_array,
1794
                actions_roles_array,
1795
                fts,
1796
                status IN ({endpoint_status}),
1797
                {formdef_name},
1798
                (SELECT name FROM users WHERE users.id = CAST(user_id AS INTEGER)),
1799
                criticality_level - {criticality_levels},
1800
                {geoloc_base_x},
1801
                {geoloc_base_y},
1802
                anonymised
1803
            FROM {table_name}
1804
            ON CONFLICT DO NOTHING;
1805
                """.format(
1806
                table_name=get_formdef_table_name(formdef),
1807
                category_id=category_value,  # always valued ? need to handle null otherwise.
1808
                formdef_id=formdef.id,
1809
                geoloc_base_x=geoloc_base_x_query,
1810
                geoloc_base_y=geoloc_base_y_query,
1811
                formdef_name=formdef_name,
1812
                criticality_levels=criticality_levels,
1813
                endpoint_status=endpoint_status_filter,
1814
                object_type=object_type,
1815
            )
1816
        )
1817

  
1818

  
1736 1819
class SqlMixin:
1737 1820
    _table_name = None
1738 1821
    _numerical_id = True
......
4139 4222
        set_reindex('formdata', 'needed', conn=conn, cur=cur)
4140 4223
    if sql_level < 59:
4141 4224
        # switch wcs_all_forms to a trigger-maintained table
4142
        from wcs.carddef import CardDef
4143
        from wcs.formdef import FormDef
4144

  
4145
        cur.execute("SELECT relkind FROM pg_class WHERE relname = 'wcs_all_forms';")
4146
        rows = cur.fetchall()
4147
        if len(rows) != 0:
4148
            if rows[0][0] == 'v':
4149
                # force wcs_all_forms table creation
4150
                cur.execute('DROP VIEW IF EXISTS wcs_all_forms CASCADE;')
4151
                do_global_views(conn, cur)
4152
            else:
4153
                assert rows[0][0] == 'r'
4154
        else:
4155
            do_global_views(conn, cur)
4156

  
4157
        # assert there is no row, ie we are doing a clean migration (special case with unit tests likely) ?
4158
        # cur.execute("SELECT COUNT(*) FROM wcs_all_forms;")
4159
        # assert(cur.fetchone()[0] == 0)
4160

  
4161
        # now copy all data into the table
4162
        for formdef in FormDef.select() + CardDef.select():
4163
            category_value = formdef.category_id
4164
            if formdef.category_id is None:
4165
                category_value = "NULL"
4166
            geoloc_base_x_query = "NULL"
4167
            geoloc_base_y_query = "NULL"
4168
            if formdef.geolocations and 'base' in formdef.geolocations:
4169
                # default geolocation is in the 'base' key; we have to unstructure the
4170
                # field is the POINT type of postgresql cannot be used directly as it
4171
                # doesn't have an equality operator.
4172
                geoloc_base_x_query = "geoloc_base[0]"
4173
                geoloc_base_y_query = "geoloc_base[1]"
4174
            criticality_levels = len(formdef.workflow.criticality_levels or [0])
4175
            endpoint_status = formdef.workflow.get_endpoint_status()
4176
            endpoint_status_filter = ", ".join(["'wf-%s'" % x.id for x in endpoint_status])
4177
            if endpoint_status_filter == "":
4178
                # not the prettiest in town, but will do fine for now.
4179
                endpoint_status_filter = "'xxxx'"
4180
            object_type = formdef.data_sql_prefix  # shortcut.
4181
            formed_name_quotedstring = psycopg2.extensions.QuotedString(formdef.name)
4182
            formed_name_quotedstring.encoding = 'utf8'
4183
            formdef_name = formed_name_quotedstring.getquoted().decode()
4184
            cur.execute(
4185
                """
4186
                INSERT INTO wcs_all_forms
4187
                SELECT
4188
                    {category_id},
4189
                    '{object_type}',
4190
                    {formdef_id},
4191
                    id,
4192
                    user_id,
4193
                    receipt_time,
4194
                    status,
4195
                    id_display,
4196
                    submission_agent_id,
4197
                    submission_channel,
4198
                    backoffice_submission,
4199
                    last_update_time,
4200
                    digests,
4201
                    user_label,
4202
                    concerned_roles_array,
4203
                    actions_roles_array,
4204
                    fts,
4205
                    status IN ({endpoint_status}),
4206
                    {formdef_name},
4207
                    (SELECT name FROM users WHERE users.id = CAST(user_id AS INTEGER)),
4208
                    criticality_level - {criticality_levels},
4209
                    {geoloc_base_x},
4210
                    {geoloc_base_y},
4211
                    anonymised
4212
                FROM {table_name}
4213
                ON CONFLICT DO NOTHING;
4214
                    """.format(
4215
                    table_name=get_formdef_table_name(formdef),
4216
                    category_id=category_value,  # always valued ? need to handle null otherwise.
4217
                    formdef_id=formdef.id,
4218
                    geoloc_base_x=geoloc_base_x_query,
4219
                    geoloc_base_y=geoloc_base_y_query,
4220
                    formdef_name=formdef_name,
4221
                    criticality_levels=criticality_levels,
4222
                    endpoint_status=endpoint_status_filter,
4223
                    object_type=object_type,
4224
                )
4225
            )
4225
        init_global_table(conn, cur)
4226 4226

  
4227 4227
    cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', (str(SQL_LEVEL[0]), 'sql_level'))
4228 4228

  
4229
-