Compare commits

..

8 Commits

3 changed files with 38 additions and 36 deletions

View File

@ -446,6 +446,7 @@ class SubmissionDirectory(Directory):
def get_submittable_formdefs(self):
user = get_request().user
agent_ids = set()
list_forms = []
for formdef in FormDef.select(order_by='name', ignore_errors=True):
if formdef.is_disabled():
@ -459,6 +460,21 @@ class SubmissionDirectory(Directory):
continue
list_forms.append(formdef)
# prefetch formdatas
data_class = formdef.data_class()
formdef._formdatas = data_class.select(
[Equal('status', 'draft'), Equal('backoffice_submission', True)]
)
formdef._formdatas.sort(key=lambda x: x.receipt_time or make_aware(datetime.datetime(1900, 1, 1)))
agent_ids.update([x.submission_agent_id for x in formdef._formdatas if x.submission_agent_id])
# prefetch agents
self.prefetched_agents = {
str(x.id): x
for x in get_publisher().user_class.get_ids(list(agent_ids), ignore_errors=True)
if x is not None
}
return list_forms
def _q_index(self):
@ -501,15 +517,6 @@ class SubmissionDirectory(Directory):
if mode != 'create':
skip = True
for formdef in formdefs:
if not hasattr(formdef, '_formdatas'):
data_class = formdef.data_class()
formdata_ids = data_class.get_ids_with_indexed_value('status', 'draft')
formdef._formdatas = [
x for x in data_class.get_ids(formdata_ids) if x.backoffice_submission is True
]
formdef._formdatas.sort(
key=lambda x: x.receipt_time or make_aware(datetime.datetime(1900, 1, 1))
)
skip &= not (bool(formdef._formdatas))
if skip:
return
@ -553,9 +560,7 @@ class SubmissionDirectory(Directory):
else _('unknown date'),
}
if formdata.submission_agent_id:
agent_user = get_publisher().user_class.get(
formdata.submission_agent_id, ignore_errors=True
)
agent_user = self.prefetched_agents.get(formdata.submission_agent_id)
if agent_user:
label += ' (%s)' % agent_user.display_name
r += htmltext('<a href="%s/%s/">%s</a>') % (formdef.url_name, formdata.id, label)
@ -568,15 +573,12 @@ class SubmissionDirectory(Directory):
count = 0
mode = get_request().form.get('mode')
for formdef in formdefs:
if not hasattr(formdef, '_formdatas'):
data_class = formdef.data_class()
formdata_ids = data_class.get_ids_with_indexed_value('status', 'draft')
formdatas = [x for x in data_class.get_ids(formdata_ids) if x.backoffice_submission is True]
if mode == 'empty':
formdatas = [x for x in formdatas if x.has_empty_data()]
elif mode == 'existing':
formdatas = [x for x in formdatas if not x.has_empty_data()]
count += len(formdatas)
formdatas = formdef._formdatas
if mode == 'empty':
formdatas = [x for x in formdatas if x.has_empty_data()]
elif mode == 'existing':
formdatas = [x for x in formdatas if not x.has_empty_data()]
count += len(formdatas)
return misc.json_response({'count': count})
def _q_lookup(self, component):

View File

@ -1705,6 +1705,20 @@ def init_search_tokens(conn=None, cur=None):
# Index at the end, small performance trick... not that useful, but it's free...
cur.execute("CREATE INDEX IF NOT EXISTS wcs_search_tokens_trgm ON wcs_search_tokens USING gin(token gin_trgm_ops);")
# And last: functions to use this brand new table
cur.execute("CREATE OR REPLACE AGGREGATE tsquery_agg_or (tsquery) (sfunc=tsquery_or, stype=tsquery);")
cur.execute("CREATE OR REPLACE AGGREGATE tsquery_agg_and (tsquery) (sfunc=tsquery_and, stype=tsquery);")
cur.execute("""CREATE OR REPLACE FUNCTION public.wcs_tsquery(text)
RETURNS tsquery
LANGUAGE sql
STABLE
AS $function$
with
tokenized as (select unnest(regexp_split_to_array($1, '\s+')) w),
super_tokenized as (select w, coalesce(tsquery_agg_or(plainto_tsquery(token) order by token <-> w desc), plainto_tsquery(w)) tokens from tokenized left join wcs_search_tokens on token % w group by w)
select tsquery_agg_and(tokens) from super_tokenized;
$function$;""")
if own_cur:
cur.close()
@ -1731,20 +1745,6 @@ $function$;""")
cur.execute("CREATE TRIGGER wcs_all_forms_fts_trg_ins AFTER INSERT ON wcs_all_forms FOR EACH ROW WHEN (NEW.fts IS NOT NULL) EXECUTE PROCEDURE wcs_search_tokens_trigger_fn();")
cur.execute("CREATE TRIGGER wcs_all_forms_fts_trg_upd AFTER UPDATE OF fts ON wcs_all_forms FOR EACH ROW WHEN (NEW.fts IS NOT NULL) EXECUTE PROCEDURE wcs_search_tokens_trigger_fn();")
# And last: functions to use this brand new table
cur.execute("CREATE OR REPLACE AGGREGATE tsquery_agg_or (tsquery) (sfunc=tsquery_or, stype=tsquery);")
cur.execute("CREATE OR REPLACE AGGREGATE tsquery_agg_and (tsquery) (sfunc=tsquery_and, stype=tsquery);")
cur.execute("""CREATE OR REPLACE FUNCTION public.wcs_tsquery(text)
RETURNS tsquery
LANGUAGE sql
STABLE
AS $function$
with
tokenized as (select unnest(regexp_split_to_array($1, '\s+')) w),
super_tokenized as (select w, coalesce(tsquery_agg_or(plainto_tsquery(token) order by token <-> w desc), plainto_tsquery(w)) tokens from tokenized left join wcs_search_tokens on token % w group by w)
select tsquery_agg_and(tokens) from super_tokenized;
$function$;""")
def init_search_tokens_data(cur):
cur.execute("INSERT INTO wcs_search_tokens SELECT unnest(tsvector_to_array(fts)) FROM wcs_all_forms ON CONFLICT(token) DO NOTHING;")

View File

@ -370,7 +370,7 @@ class FtsMatch(Criteria):
return unidecode.unidecode(value)
def as_sql(self):
return 'fts @@ plainto_tsquery(%%(c%s)s)' % id(self.value)
return 'fts @@ wcs_tsquery(%%(c%s)s)' % id(self.value)
class ElementEqual(Criteria):