Projet

Général

Profil

0001-sql-delay-re-index-operations-on-first-cron-22383.patch

Thomas Noël, 20 avril 2018 11:32

Télécharger (7,41 ko)

Voir les différences:

Subject: [PATCH] sql: delay re-index operations on first cron (#22383)

 tests/test_sql.py  | 44 ++++++++++++++-----------------------
 wcs/publisher.py   |  4 ++++
 wcs/qommon/cron.py |  5 +++++
 wcs/sql.py         | 55 ++++++++++++++++++++++++++++++++++++++++------
 4 files changed, 74 insertions(+), 34 deletions(-)
tests/test_sql.py
8 8
import sys
9 9
import time
10 10

  
11
from django.core.management import call_command
12

  
11 13
from quixote import cleanup
12 14

  
13 15
from wcs import formdef, publisher, fields
......
19 21
from wcs import sql
20 22
import wcs.qommon.storage as st
21 23

  
22
from utilities import create_temporary_pub
24
from utilities import create_temporary_pub, clean_temporary_pub
23 25

  
24 26
import pytest
25 27
postgresql = pytest.mark.postgresql
......
34 36

  
35 37
    cleanup()
36 38

  
37
    pub = create_temporary_pub()
38
    pub.user_class = sql.SqlUser
39
    pub.is_using_postgresql = lambda: True
40

  
41
    conn = psycopg2.connect(user=os.environ['USER'])
42
    conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
43
    cur = conn.cursor()
44
    dbname = 'wcstests%d' % random.randint(0, 100000)
45
    cur.execute('CREATE DATABASE %s' % dbname)
46
    cur.close()
47

  
48
    pub.cfg['postgresql'] = {'database': dbname, 'user': os.environ['USER']}
49
    pub.initialize_sql()
39
    pub = create_temporary_pub(sql_mode=True)
50 40

  
51 41
    formdef = formdef.FormDef()
52 42
    formdef.name = 'tests'
......
61 51
    ]
62 52
    formdef.store()
63 53

  
64
    conn.close()
65

  
66

  
67 54
def teardown_module(module):
68
    shutil.rmtree(pub.APP_DIR)
69

  
70
    if hasattr(pub, 'pgconn') and pub.pgconn:
71
        pub.pgconn.close()
72

  
73
    conn = psycopg2.connect(user=os.environ['USER'])
74
    conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
75
    cur = conn.cursor()
76
    cur.execute('DROP DATABASE %s' % pub.cfg['postgresql']['database'])
77
    cur.close()
55
    clean_temporary_pub()
78 56

  
79 57
@postgresql
80 58
def test_sql_table_name_invalid_chars():
......
1098 1076
    assert column_exists_in_table(cur, 'users', 'fts')
1099 1077
    assert migration_level(cur) >= 12
1100 1078

  
1079
    assert sql.is_reindex_needed('user', conn=conn, cur=cur) is True
1080
    assert sql.is_reindex_needed('formdata', conn=conn, cur=cur) is True
1081
    call_command('cron')  # first cron = reindex
1082
    assert sql.is_reindex_needed('user', conn=conn, cur=cur) is False
1083
    assert sql.is_reindex_needed('formdata', conn=conn, cur=cur) is False
1084

  
1101 1085
    # make sure the fts is filled after the migration
1102 1086
    assert len(sql.SqlUser.get_ids_from_query('pierre')) == 1
1103 1087

  
......
1123 1107
    assert column_exists_in_table(cur, 'users', 'ascii_name')
1124 1108
    assert migration_level(cur) >= 21
1125 1109

  
1110
    assert sql.is_reindex_needed('user', conn=conn, cur=cur) is True
1111
    assert sql.is_reindex_needed('formdata', conn=conn, cur=cur) is True
1112
    call_command('cron')  # first cron = reindex
1113
    assert sql.is_reindex_needed('user', conn=conn, cur=cur) is False
1114
    assert sql.is_reindex_needed('formdata', conn=conn, cur=cur) is False
1115

  
1126 1116
    # make sure the ascii_name is filled after the migration
1127 1117
    assert sql.SqlUser.count([st.Equal('ascii_name', 'jean senisme')]) == 1
1128 1118

  
wcs/publisher.py
298 298
        import sql
299 299
        sql.migrate()
300 300

  
301
    def reindex_sql(self):
302
        import sql
303
        sql.reindex()
304

  
301 305
    def cleanup(self):
302 306
        if self.is_using_postgresql():
303 307
            import sql
wcs/qommon/cron.py
35 35
        publisher.set_config()
36 36
    except:
37 37
        return
38

  
39
    # reindex user and formdata if needed (should only be run once)
40
    if publisher.is_using_postgresql():
41
        publisher.reindex_sql()
42

  
38 43
    for job in publisher.cronjobs:
39 44
        if job.days and now[2] not in job.days:
40 45
            continue
wcs/sql.py
2102 2102
    sql_level = int(cur.fetchone()[0])
2103 2103
    return sql_level
2104 2104

  
2105
@guard_postgres
2106
def is_reindex_needed(index, conn, cur):
2107
    do_meta_table(conn, cur, insert_current_sql_level=False)
2108
    key_name = 'reindex_%s' % index
2109
    cur.execute('''SELECT value FROM wcs_meta WHERE key = %s''', (key_name, ))
2110
    row = cur.fetchone()
2111
    if row is None:
2112
        cur.execute('''INSERT INTO wcs_meta (id, key, value)
2113
                       VALUES (DEFAULT, %s, %s)''', (key_name, 'no'))
2114
        return False
2115
    return row[0] == 'needed'
2116

  
2117
@guard_postgres
2118
def set_reindex(index, value, conn, cur):
2119
    do_meta_table(conn, cur, insert_current_sql_level=False)
2120
    key_name = 'reindex_%s' % index
2121
    cur.execute('''SELECT value FROM wcs_meta WHERE key = %s''', (key_name, ))
2122
    row = cur.fetchone()
2123
    if row is None:
2124
        cur.execute('''INSERT INTO wcs_meta (id, key, value)
2125
                       VALUES (DEFAULT, %s, %s)''', (key_name, value))
2126
    else:
2127
        cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', (
2128
                    value, key_name))
2129

  
2105 2130
def migrate_views(conn, cur):
2106 2131
    drop_views(None, conn, cur)
2107 2132
    from wcs.formdef import FormDef
......
2151 2176
        # 12: (second part), store fts in existing rows
2152 2177
        # 21: (second part), store ascii_name of users
2153 2178
        # 23: (first part), use misc.simplify() over full text queries
2154
        for user_id in SqlUser.keys():
2155
            SqlUser.get(user_id).store()
2179
        set_reindex('user', 'needed', conn=conn, cur=cur)
2156 2180
    if sql_level < 23:
2157 2181
        # 17: store last_update_time in tables
2158 2182
        # 18: add user name to full-text search index
2159 2183
        # 21: (third part), add user ascii_names to full-text index
2160 2184
        # 23: (second part) use misc.simplify() over full text queries
2161
        # load and store all formdatas
2162
        from wcs.formdef import FormDef
2163
        for formdef in FormDef.select():
2164
            for formdata in formdef.data_class().select():
2165
                formdata.store()
2185
        set_reindex('formdata', 'needed', conn=conn, cur=cur)
2166 2186
    if sql_level < 24:
2167 2187
        from wcs.formdef import FormDef
2168 2188
        # 24: add index on evolution(formdata_id)
......
2176 2196

  
2177 2197
    conn.commit()
2178 2198
    cur.close()
2199

  
2200

  
2201
@guard_postgres
2202
def reindex():
2203
    conn, cur = get_connection_and_cursor()
2204

  
2205
    if is_reindex_needed('user', conn=conn, cur=cur):
2206
        for user_id in SqlUser.keys():
2207
            SqlUser.get(user_id).store()
2208
        set_reindex('user', 'done', conn=conn, cur=cur)
2209

  
2210
    if is_reindex_needed('formdata', conn=conn, cur=cur):
2211
        # load and store all formdatas
2212
        from wcs.formdef import FormDef
2213
        for formdef in FormDef.select():
2214
            for formdata in formdef.data_class().select():
2215
                formdata.store()
2216
        set_reindex('formdata', 'done', conn=conn, cur=cur)
2217

  
2218
    conn.commit()
2219
    cur.close()
2179
-