Projet

Général

Profil

0008-sql-do-not-include-carddata-in-wcs_all_forms-60552.patch

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

Télécharger (9,3 ko)

Voir les différences:

Subject: [PATCH 8/9] sql: do not include carddata in wcs_all_forms (#60552)

 wcs/sql.py | 113 +++++++++++++++++++++++++----------------------------
 1 file changed, 53 insertions(+), 60 deletions(-)
wcs/sql.py
574 574
    row = cur.fetchone()
575 575
    # only do the delete if wcs_all_forms is a table and not still a view
576 576
    if row is not None and row[0] == 'r':
577
        cur.execute("DELETE FROM wcs_all_forms WHERE object_type = 'formdata'")
577
        cur.execute('TRUNCATE wcs_all_forms')
578 578
    conn.commit()
579 579
    cur.close()
580 580

  
......
792 792
    for field in existing_fields - needed_fields:
793 793
        cur.execute('''ALTER TABLE %s DROP COLUMN %s CASCADE''' % (table_name, field))
794 794

  
795
    if formdef.data_sql_prefix == 'formdata':
796
        recreate_trigger(formdef, cur, conn)
797

  
798
    # migrations on _evolutions table
799
    cur.execute(
800
        '''SELECT column_name FROM information_schema.columns
801
                    WHERE table_schema = 'public'
802
                      AND table_name = '%s_evolutions'
803
                '''
804
        % table_name
805
    )
806
    evo_existing_fields = {x[0] for x in cur.fetchall()}
807
    if 'last_jump_datetime' not in evo_existing_fields:
808
        cur.execute('''ALTER TABLE %s_evolutions ADD COLUMN last_jump_datetime timestamp''' % table_name)
809

  
810
    if rebuild_views or len(existing_fields - needed_fields):
811
        # views may have been dropped when dropping columns, so we recreate
812
        # them even if not asked to.
813
        redo_views(conn, cur, formdef, rebuild_global_views=rebuild_global_views)
814

  
815
    if new_table:
816
        do_formdef_indexes(formdef, created=True, conn=conn, cur=cur)
817

  
818
    if own_conn:
819
        conn.commit()
820
        cur.close()
821

  
822
    actions = []
823
    if 'concerned_roles_array' not in existing_fields:
824
        actions.append('rebuild_security')
825
    elif 'actions_roles_array' not in existing_fields:
826
        actions.append('rebuild_security')
827
    if 'tracking_code' not in existing_fields:
828
        # if tracking code has just been added to the table we need to make
829
        # sure the tracking code table does exist.
830
        actions.append('do_tracking_code_table')
831

  
832
    return actions
833

  
834

  
835
def recreate_trigger(formdef, cur, conn):
795 836
    # recreate the trigger function, just so it's uptodate
837
    table_name = get_formdef_table_name(formdef)
796 838
    category_value = formdef.category_id
797 839
    geoloc_base_x_query = "NULL"
798 840
    geoloc_base_y_query = "NULL"
......
810 852
    if endpoint_status_filter == "":
811 853
        # not the prettiest in town, but will do fine for now.
812 854
        endpoint_status_filter = "'xxxx'"
813
    object_type = formdef.data_sql_prefix  # shortcut.
814 855
    formed_name_quotedstring = psycopg2.extensions.QuotedString(formdef.name)
815 856
    formed_name_quotedstring.encoding = 'utf8'
816 857
    formdef_name = formed_name_quotedstring.getquoted().decode()
......
823 864
BEGIN
824 865
    -- TODO : sync back from users change !
825 866
    IF TG_OP = 'DELETE' THEN
826
        DELETE FROM wcs_all_forms WHERE formdef_id = {formdef_id} AND id = OLD.id AND object_type = '{object_type}';
867
        DELETE FROM wcs_all_forms WHERE formdef_id = {formdef_id} AND id = OLD.id;
827 868
        RETURN OLD;
828 869
    ELSEIF TG_OP = 'INSERT' THEN
829 870
        INSERT INTO wcs_all_forms VALUES (
830 871
            {category_id},
831
            '{object_type}',
832 872
            {formdef_id},
833 873
            NEW.id,
834 874
            NEW.user_id,
......
874 914
                geoloc_base_x = {geoloc_base_x},
875 915
                geoloc_base_y = {geoloc_base_y},
876 916
                anonymised = NEW.anonymised
877
            WHERE formdef_id = {formdef_id}  AND id = OLD.id AND object_type = '{object_type}';
917
            WHERE formdef_id = {formdef_id} AND id = OLD.id;
878 918
        RETURN NEW;
879 919
    END IF;
880 920
END;
......
888 928
            formdef_name=formdef_name,
889 929
            criticality_levels=criticality_levels,
890 930
            endpoint_status=endpoint_status_filter,
891
            object_type=object_type,
892 931
        )
893 932
    )
894 933

  
......
912 951
            )
913 952
        )
914 953

  
915
    # migrations on _evolutions table
916
    cur.execute(
917
        '''SELECT column_name FROM information_schema.columns
918
                    WHERE table_schema = 'public'
919
                      AND table_name = '%s_evolutions'
920
                '''
921
        % table_name
922
    )
923
    evo_existing_fields = {x[0] for x in cur.fetchall()}
924
    if 'last_jump_datetime' not in evo_existing_fields:
925
        cur.execute('''ALTER TABLE %s_evolutions ADD COLUMN last_jump_datetime timestamp''' % table_name)
926

  
927
    if rebuild_views or len(existing_fields - needed_fields):
928
        # views may have been dropped when dropping columns, so we recreate
929
        # them even if not asked to.
930
        redo_views(conn, cur, formdef, rebuild_global_views=rebuild_global_views)
931

  
932
    if new_table:
933
        do_formdef_indexes(formdef, created=True, conn=conn, cur=cur)
934

  
935
    if own_conn:
936
        conn.commit()
937
        cur.close()
938

  
939
    actions = []
940
    if 'concerned_roles_array' not in existing_fields:
941
        actions.append('rebuild_security')
942
    elif 'actions_roles_array' not in existing_fields:
943
        actions.append('rebuild_security')
944
    if 'tracking_code' not in existing_fields:
945
        # if tracking code has just been added to the table we need to make
946
        # sure the tracking code table does exist.
947
        actions.append('do_tracking_code_table')
948

  
949
    return actions
950

  
951 954

  
952 955
def do_formdef_indexes(formdef, created, conn, cur, concurrently=False):
953 956
    table_name = get_formdef_table_name(formdef)
......
1664 1667

  
1665 1668
def do_global_views(conn, cur):
1666 1669
    # recreate global views
1667
    from .carddef import CardDef
1668 1670
    from .formdef import FormDef
1669 1671

  
1670 1672
    # XXX TODO: make me dynamic, please ?
1671 1673
    cur.execute(
1672 1674
        """CREATE TABLE IF NOT EXISTS wcs_all_forms (
1673 1675
        category_id integer,
1674
        object_type character varying NOT NULL, -- formdef or carddef
1675 1676
        formdef_id integer NOT NULL,
1676 1677
        id integer NOT NULL,
1677 1678
        user_id character varying,
......
1694 1695
        geoloc_base_x double precision,
1695 1696
        geoloc_base_y double precision,
1696 1697
        anonymised timestamp with time zone
1697
        , PRIMARY KEY(object_type, formdef_id, id)
1698
        , PRIMARY KEY(formdef_id, id)
1698 1699
    )"""
1699 1700
    )
1700 1701
    cur.execute(
......
1712 1713
        )
1713 1714

  
1714 1715
    # Purge of any dead data
1715
    valid_data = {FormDef.data_sql_prefix: set(), CardDef.data_sql_prefix: set()}
1716
    valid_ids = set()
1716 1717
    for formdef in FormDef.select(ignore_migration=True):
1717
        valid_data[formdef.data_sql_prefix].add(formdef.id)
1718
    for object_type, valid_ids in valid_data.items():
1719
        if valid_ids:
1720
            cur.execute(
1721
                "DELETE FROM wcs_all_forms WHERE object_type = '%s' AND formdef_id NOT IN (%s)"
1722
                % (object_type, ", ".join(valid_ids))
1723
            )
1724
        else:
1725
            cur.execute("DELETE FROM wcs_all_forms WHERE object_type = '%s'" % object_type)
1718
        valid_ids.add(int(formdef.id))
1719
    if valid_ids:
1720
        cur.execute('DELETE FROM wcs_all_forms WHERE NOT formdef_id = ANY(%s)', (list(valid_ids),))
1721
    else:
1722
        cur.execute('TRUNCATE wcs_all_forms')
1726 1723

  
1727 1724
    for category in wcs.categories.Category.select():
1728 1725
        name = get_name_as_sql_identifier(category.url_name)[:40]
......
1734 1731

  
1735 1732

  
1736 1733
def init_global_table(conn=None, cur=None):
1737
    from .carddef import CardDef
1738 1734
    from .formdef import FormDef
1739 1735

  
1740 1736
    own_conn = False
......
1755 1751
    do_global_views(conn, cur)
1756 1752

  
1757 1753
    # now copy all data into the table
1758
    for formdef in FormDef.select() + CardDef.select():
1754
    for formdef in FormDef.select():
1759 1755
        category_value = formdef.category_id
1760 1756
        if formdef.category_id is None:
1761 1757
            category_value = "NULL"
......
1773 1769
        if endpoint_status_filter == "":
1774 1770
            # not the prettiest in town, but will do fine for now.
1775 1771
            endpoint_status_filter = "'xxxx'"
1776
        object_type = formdef.data_sql_prefix  # shortcut.
1777 1772
        formed_name_quotedstring = psycopg2.extensions.QuotedString(formdef.name)
1778 1773
        formed_name_quotedstring.encoding = 'utf8'
1779 1774
        formdef_name = formed_name_quotedstring.getquoted().decode()
......
1782 1777
            INSERT INTO wcs_all_forms
1783 1778
            SELECT
1784 1779
                {category_id},
1785
                '{object_type}',
1786 1780
                {formdef_id},
1787 1781
                id,
1788 1782
                user_id,
......
1816 1810
                formdef_name=formdef_name,
1817 1811
                criticality_levels=criticality_levels,
1818 1812
                endpoint_status=endpoint_status_filter,
1819
                object_type=object_type,
1820 1813
            )
1821 1814
        )
1822 1815

  
1823
-