mirror of
https://github.com/evennia/evennia.git
synced 2026-04-05 15:37:17 +02:00
Updated create.create_object to be faster. Made AttributeHandler.add() handle bulk-adding of Attributes and with a slightly more efficient way to create new Attributes.
This commit is contained in:
parent
cda13989f6
commit
05d21ef4f7
3 changed files with 74 additions and 30 deletions
|
|
@ -321,6 +321,12 @@ class AttributeHandler(object):
|
|||
return ret if len(key) > 1 else default
|
||||
return ret[0] if len(ret)==1 else ret
|
||||
|
||||
def batch_add(self, keys, values, categories=None, lockstrings=None,
|
||||
stratts=None, accessing_obj=None, default_access=True):
|
||||
"""
|
||||
Batch version supporting the addition of more than one
|
||||
"""
|
||||
|
||||
def add(self, key, value, category=None, lockstring="",
|
||||
strattr=False, accessing_obj=None, default_access=True):
|
||||
"""
|
||||
|
|
@ -332,6 +338,12 @@ class AttributeHandler(object):
|
|||
If accessing_obj is given, self.obj's 'attrcreate' lock access
|
||||
will be checked against it. If no accessing_obj is given, no check
|
||||
will be done.
|
||||
|
||||
The method also accepts multiple attributes (this is a faster way
|
||||
to add attributes since it allows for some optimizations).
|
||||
If so, key and value (or strvalue) must be iterables of the same length.
|
||||
All batch-added Attributes will use the same category and lockstring.
|
||||
|
||||
"""
|
||||
if accessing_obj and not self.obj.access(accessing_obj,
|
||||
self._attrcreate, default=default_access):
|
||||
|
|
@ -341,28 +353,41 @@ class AttributeHandler(object):
|
|||
self._recache()
|
||||
if not key:
|
||||
return
|
||||
key = key.strip().lower()
|
||||
|
||||
keys, values= make_iter(key), make_iter(value)
|
||||
|
||||
if len(keys) != len(values):
|
||||
raise RuntimeError("AttributeHandler.add(): key and value of different length: %s vs %s" % key, value)
|
||||
category = category.strip().lower() if category is not None else None
|
||||
cachekey = "%s-%s" % (key, category)
|
||||
attr_obj = self._cache.get(cachekey)
|
||||
if not attr_obj:
|
||||
# no old attr available; create new.
|
||||
attr_obj = Attribute(db_key=key, db_category=category,
|
||||
db_model=self._model, db_attrtype=self._attrtype)
|
||||
attr_obj.save() # important
|
||||
getattr(self.obj, self._m2m_fieldname).add(attr_obj)
|
||||
self._cache[cachekey] = attr_obj
|
||||
if lockstring:
|
||||
attr_obj.locks.add(lockstring)
|
||||
# we shouldn't need to fear stale objects, the field signalling
|
||||
# should catch all cases
|
||||
if strattr:
|
||||
# store as a simple string
|
||||
attr_obj.db_strvalue = value
|
||||
attr_obj.save(update_fields=["db_strvalue"])
|
||||
else:
|
||||
# pickle arbitrary data
|
||||
attr_obj.value = value
|
||||
new_attrobjs = []
|
||||
for ikey, keystr in enumerate(keys):
|
||||
keystr = keystr.strip().lower()
|
||||
new_value = values[ikey]
|
||||
cachekey = "%s-%s" % (keystr, category)
|
||||
attr_obj = self._cache.get(cachekey)
|
||||
|
||||
if attr_obj:
|
||||
# update an existing attribute object
|
||||
if strattr:
|
||||
# store as a simple string (will not notify OOB handlers)
|
||||
attr_obj.db_strvalue = new_value
|
||||
attr_obj.save(update_fields=["db_strvalue"])
|
||||
else:
|
||||
# store normally (this will also notify OOB handlers)
|
||||
attr_obj.value = new_value
|
||||
else:
|
||||
# create a new Attribute (no OOB handlers can be notified)
|
||||
kwargs = {"db_key" : keystr, "db_category" : category,
|
||||
"db_model" : self._model, "db_attrtype" : self._attrtype,
|
||||
"db_value" : None if strattr else to_pickle(new_value),
|
||||
"db_strvalue" : value if strattr else None}
|
||||
new_attr = Attribute(**kwargs)
|
||||
new_attr.save()
|
||||
new_attrobjs.append(new_attr)
|
||||
if new_attrobjs:
|
||||
# Add new objects to m2m field all at once
|
||||
getattr(self.obj, self._m2m_fieldname).add(*new_attrobjs)
|
||||
self._recache()
|
||||
|
||||
def remove(self, key, raise_exception=False, category=None,
|
||||
accessing_obj=None, default_access=True):
|
||||
|
|
@ -581,8 +606,10 @@ class TagHandler(object):
|
|||
self.obj, self._m2m_fieldname).filter(
|
||||
db_model=self._model).filter(tagtype))
|
||||
|
||||
def add(self, tag, category=None, data=None):
|
||||
def add(self, tag=None, category=None, data=None):
|
||||
"Add a new tag to the handler. Tag is a string or a list of strings."
|
||||
if not tag:
|
||||
return
|
||||
for tagstr in make_iter(tag):
|
||||
if not tagstr:
|
||||
continue
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue