Fix optimized prototype search mechanism. Still no dual db/mod search

This commit is contained in:
Griatch 2020-09-14 19:13:18 +02:00
parent f61c80caf7
commit 7307887185
3 changed files with 29 additions and 25 deletions

View file

@ -38,9 +38,7 @@ without arguments starts a full interactive Python console.
of texts (such as tables). New `justify` bool. Old `justify_kwargs` remains of texts (such as tables). New `justify` bool. Old `justify_kwargs` remains
but is now only used to pass extra kwargs into the justify function. but is now only used to pass extra kwargs into the justify function.
- EvMore `text` argument can now also be a list or a queryset. Querysets will be - EvMore `text` argument can now also be a list or a queryset. Querysets will be
sliced to only return the required data per page. EvMore takes a new kwarg sliced to only return the required data per page.
`page_formatter` which will be called for each page. This allows to customize
the display of queryset data, build a new EvTable per page etc.
- Improve performance of `find` and `objects` commands on large data sets (strikaco) - Improve performance of `find` and `objects` commands on large data sets (strikaco)
- New `CHANNEL_HANDLER_CLASS` setting allows for replacing the ChannelHandler entirely. - New `CHANNEL_HANDLER_CLASS` setting allows for replacing the ChannelHandler entirely.
- Made `py` interactive mode support regular quit() and more verbose. - Made `py` interactive mode support regular quit() and more verbose.

View file

@ -410,22 +410,13 @@ def search_prototype(key=None, tags=None, require_single=False, return_iterators
.filter(scriptdb__pk__in=db_ids, db_key="prototype") .filter(scriptdb__pk__in=db_ids, db_key="prototype")
.values_list("db_value", flat=True) .values_list("db_value", flat=True)
) )
if key: if key and require_single:
matches = list(db_matches) + module_prototypes nmodules = len(module_prototypes)
nmatches = len(matches) ndbprots = db_matches.count()
if nmatches > 1: if nmodules + ndbprots != 1:
key = key.lower() raise KeyError(f"Found {nmodules + ndbprots} matching prototypes.")
# avoid duplicates if an exact match exist between the two types
filter_matches = [ if return_iterators:
mta for mta in matches if mta.get("prototype_key") and mta["prototype_key"] == key
]
if filter_matches and len(filter_matches) < nmatches:
matches = filter_matches
nmatches = len(matches)
if nmatches != 1 and require_single:
raise KeyError("Found {} matching prototypes.".format(nmatches))
return matches
elif return_iterators:
# trying to get the entire set of prototypes - we must paginate # trying to get the entire set of prototypes - we must paginate
# the result instead of trying to fetch the entire set at once # the result instead of trying to fetch the entire set at once
db_pages = Paginator(db_matches, 20) db_pages = Paginator(db_matches, 20)
@ -479,6 +470,8 @@ class PrototypeEvMore(EvMore):
# get use-permissions of readonly attributes (edit is always False) # get use-permissions of readonly attributes (edit is always False)
display_tuples = [] display_tuples = []
print("page", page)
for prototype in page: for prototype in page:
lock_use = caller.locks.check_lockstring( lock_use = caller.locks.check_lockstring(
caller, prototype.get("prototype_locks", ""), access_type="spawn", default=True caller, prototype.get("prototype_locks", ""), access_type="spawn", default=True
@ -538,16 +531,23 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False, show_non_ed
show_non_edit (bool, optional): Show also prototypes the caller may not edit. show_non_edit (bool, optional): Show also prototypes the caller may not edit.
session (Session, optional): If given, this is used for display formatting. session (Session, optional): If given, this is used for display formatting.
Returns: Returns:
table (EvTable or None): An EvTable representation of the prototypes. None PrototypeEvMore: An EvMore subclass optimized for prototype listings.
if no prototypes were found. None: If a `key` was given and no matches was found. In this case the caller
has already been notified.
""" """
# this allows us to pass lists of empty strings # this allows us to pass lists of empty strings
tags = [tag for tag in make_iter(tags) if tag] tags = [tag for tag in make_iter(tags) if tag]
if key is not None: if key is not None:
matches = search_prototype(key, tags)
if not matches:
caller.msg("No prototypes found.", session=session)
return None
if len(matches) < 2:
matches = [matches]
# get specific prototype (one value or exception) # get specific prototype (one value or exception)
return PrototypeEvMore(caller, [search_prototype(key, tags)], return PrototypeEvMore(caller, matches,
session=session, session=session,
show_non_use=show_non_use, show_non_use=show_non_use,
show_non_edit=show_non_edit) show_non_edit=show_non_edit)

View file

@ -248,6 +248,9 @@ class EvMore(object):
""" """
Pretty-print the page. Pretty-print the page.
""" """
pos = 0
text = "[no content]"
if self._npages > 0:
pos = self._npos pos = self._npos
text = self.page_formatter(self.paginator(pos)) text = self.page_formatter(self.paginator(pos))
if show_footer: if show_footer:
@ -447,6 +450,7 @@ class EvMore(object):
if inherits_from(inp, "evennia.utils.evtable.EvTable"): if inherits_from(inp, "evennia.utils.evtable.EvTable"):
# an EvTable # an EvTable
self.init_evtable(inp) self.init_evtable(inp)
self._paginator = self.paginator_index
elif isinstance(inp, QuerySet): elif isinstance(inp, QuerySet):
# a queryset # a queryset
self.init_queryset(inp) self.init_queryset(inp)
@ -457,13 +461,15 @@ class EvMore(object):
elif not isinstance(inp, str): elif not isinstance(inp, str):
# anything else not a str # anything else not a str
self.init_iterable(inp) self.init_iterable(inp)
self._paginator = self.paginator_django self._paginator = self.paginator_index
elif "\f" in inp: elif "\f" in inp:
# string with \f line-break markers in it # string with \f line-break markers in it
self.init_f_str(inp) self.init_f_str(inp)
self._paginator = self.paginator_index
else: else:
# a string # a string
self.init_str(inp) self.init_str(inp)
self._paginator = self.paginator_index
def paginator(self, pageno): def paginator(self, pageno):
""" """