0001-sql-delay-re-index-operations-on-first-cron-22383.patch
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 |
- |