From e986fe54e80e0d2bb7c52f02063fcf84cf31c2df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sat, 19 Mar 2022 14:22:51 +0100
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(-)

diff --git a/wcs/sql.py b/wcs/sql.py
index 7d1205872..30b793e7d 100644
--- a/wcs/sql.py
+++ b/wcs/sql.py
@@ -1733,6 +1733,89 @@ def do_global_views(conn, cur):
         )
 
 
+def init_global_table(conn, cur):
+    from .carddef import CardDef
+    from .formdef import FormDef
+
+    cur.execute("SELECT relkind FROM pg_class WHERE relname = 'wcs_all_forms';")
+    rows = cur.fetchall()
+    if len(rows) != 0:
+        if rows[0][0] == 'v':
+            # force wcs_all_forms table creation
+            cur.execute('DROP VIEW IF EXISTS wcs_all_forms CASCADE;')
+            do_global_views(conn, cur)
+        else:
+            assert rows[0][0] == 'r'
+    else:
+        do_global_views(conn, cur)
+
+    # now copy all data into the table
+    for formdef in FormDef.select() + CardDef.select():
+        category_value = formdef.category_id
+        if formdef.category_id is None:
+            category_value = "NULL"
+        geoloc_base_x_query = "NULL"
+        geoloc_base_y_query = "NULL"
+        if formdef.geolocations and 'base' in formdef.geolocations:
+            # default geolocation is in the 'base' key; we have to unstructure the
+            # field is the POINT type of postgresql cannot be used directly as it
+            # doesn't have an equality operator.
+            geoloc_base_x_query = "geoloc_base[0]"
+            geoloc_base_y_query = "geoloc_base[1]"
+        criticality_levels = len(formdef.workflow.criticality_levels or [0])
+        endpoint_status = formdef.workflow.get_endpoint_status()
+        endpoint_status_filter = ", ".join(["'wf-%s'" % x.id for x in endpoint_status])
+        if endpoint_status_filter == "":
+            # not the prettiest in town, but will do fine for now.
+            endpoint_status_filter = "'xxxx'"
+        object_type = formdef.data_sql_prefix  # shortcut.
+        formed_name_quotedstring = psycopg2.extensions.QuotedString(formdef.name)
+        formed_name_quotedstring.encoding = 'utf8'
+        formdef_name = formed_name_quotedstring.getquoted().decode()
+        cur.execute(
+            """
+            INSERT INTO wcs_all_forms
+            SELECT
+                {category_id},
+                '{object_type}',
+                {formdef_id},
+                id,
+                user_id,
+                receipt_time,
+                status,
+                id_display,
+                submission_agent_id,
+                submission_channel,
+                backoffice_submission,
+                last_update_time,
+                digests,
+                user_label,
+                concerned_roles_array,
+                actions_roles_array,
+                fts,
+                status IN ({endpoint_status}),
+                {formdef_name},
+                (SELECT name FROM users WHERE users.id = CAST(user_id AS INTEGER)),
+                criticality_level - {criticality_levels},
+                {geoloc_base_x},
+                {geoloc_base_y},
+                anonymised
+            FROM {table_name}
+            ON CONFLICT DO NOTHING;
+                """.format(
+                table_name=get_formdef_table_name(formdef),
+                category_id=category_value,  # always valued ? need to handle null otherwise.
+                formdef_id=formdef.id,
+                geoloc_base_x=geoloc_base_x_query,
+                geoloc_base_y=geoloc_base_y_query,
+                formdef_name=formdef_name,
+                criticality_levels=criticality_levels,
+                endpoint_status=endpoint_status_filter,
+                object_type=object_type,
+            )
+        )
+
+
 class SqlMixin:
     _table_name = None
     _numerical_id = True
@@ -4139,90 +4222,7 @@ def migrate():
         set_reindex('formdata', 'needed', conn=conn, cur=cur)
     if sql_level < 59:
         # switch wcs_all_forms to a trigger-maintained table
-        from wcs.carddef import CardDef
-        from wcs.formdef import FormDef
-
-        cur.execute("SELECT relkind FROM pg_class WHERE relname = 'wcs_all_forms';")
-        rows = cur.fetchall()
-        if len(rows) != 0:
-            if rows[0][0] == 'v':
-                # force wcs_all_forms table creation
-                cur.execute('DROP VIEW IF EXISTS wcs_all_forms CASCADE;')
-                do_global_views(conn, cur)
-            else:
-                assert rows[0][0] == 'r'
-        else:
-            do_global_views(conn, cur)
-
-        # assert there is no row, ie we are doing a clean migration (special case with unit tests likely) ?
-        # cur.execute("SELECT COUNT(*) FROM wcs_all_forms;")
-        # assert(cur.fetchone()[0] == 0)
-
-        # now copy all data into the table
-        for formdef in FormDef.select() + CardDef.select():
-            category_value = formdef.category_id
-            if formdef.category_id is None:
-                category_value = "NULL"
-            geoloc_base_x_query = "NULL"
-            geoloc_base_y_query = "NULL"
-            if formdef.geolocations and 'base' in formdef.geolocations:
-                # default geolocation is in the 'base' key; we have to unstructure the
-                # field is the POINT type of postgresql cannot be used directly as it
-                # doesn't have an equality operator.
-                geoloc_base_x_query = "geoloc_base[0]"
-                geoloc_base_y_query = "geoloc_base[1]"
-            criticality_levels = len(formdef.workflow.criticality_levels or [0])
-            endpoint_status = formdef.workflow.get_endpoint_status()
-            endpoint_status_filter = ", ".join(["'wf-%s'" % x.id for x in endpoint_status])
-            if endpoint_status_filter == "":
-                # not the prettiest in town, but will do fine for now.
-                endpoint_status_filter = "'xxxx'"
-            object_type = formdef.data_sql_prefix  # shortcut.
-            formed_name_quotedstring = psycopg2.extensions.QuotedString(formdef.name)
-            formed_name_quotedstring.encoding = 'utf8'
-            formdef_name = formed_name_quotedstring.getquoted().decode()
-            cur.execute(
-                """
-                INSERT INTO wcs_all_forms
-                SELECT
-                    {category_id},
-                    '{object_type}',
-                    {formdef_id},
-                    id,
-                    user_id,
-                    receipt_time,
-                    status,
-                    id_display,
-                    submission_agent_id,
-                    submission_channel,
-                    backoffice_submission,
-                    last_update_time,
-                    digests,
-                    user_label,
-                    concerned_roles_array,
-                    actions_roles_array,
-                    fts,
-                    status IN ({endpoint_status}),
-                    {formdef_name},
-                    (SELECT name FROM users WHERE users.id = CAST(user_id AS INTEGER)),
-                    criticality_level - {criticality_levels},
-                    {geoloc_base_x},
-                    {geoloc_base_y},
-                    anonymised
-                FROM {table_name}
-                ON CONFLICT DO NOTHING;
-                    """.format(
-                    table_name=get_formdef_table_name(formdef),
-                    category_id=category_value,  # always valued ? need to handle null otherwise.
-                    formdef_id=formdef.id,
-                    geoloc_base_x=geoloc_base_x_query,
-                    geoloc_base_y=geoloc_base_y_query,
-                    formdef_name=formdef_name,
-                    criticality_levels=criticality_levels,
-                    endpoint_status=endpoint_status_filter,
-                    object_type=object_type,
-                )
-            )
+        init_global_table(conn, cur)
 
     cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', (str(SQL_LEVEL[0]), 'sql_level'))
 
-- 
2.35.1

