Added fix to object.contents cache as well as reworked the extent of cache hooks on location modification.
This commit is contained in:
parent
07af616b67
commit
06a0bea8d6
11 changed files with 125 additions and 653 deletions
|
|
@ -421,7 +421,6 @@ class CmdCreate(ObjManipCommand):
|
||||||
if 'drop' in self.switches:
|
if 'drop' in self.switches:
|
||||||
if caller.location:
|
if caller.location:
|
||||||
obj.home = caller.location
|
obj.home = caller.location
|
||||||
print "Doing the drop"
|
|
||||||
obj.move_to(caller.location, quiet=True)
|
obj.move_to(caller.location, quiet=True)
|
||||||
if string:
|
if string:
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,7 @@ class ChannelManager(models.Manager):
|
||||||
ostring - the key or database id of the channel.
|
ostring - the key or database id of the channel.
|
||||||
"""
|
"""
|
||||||
channels = []
|
channels = []
|
||||||
|
if not ostring: return channels
|
||||||
try:
|
try:
|
||||||
# try an id match first
|
# try an id match first
|
||||||
dbref = int(ostring.strip('#'))
|
dbref = int(ostring.strip('#'))
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ class ObjectManager(TypedObjectManager):
|
||||||
|
|
||||||
excludeobj - one or more object keys to exclude from the match
|
excludeobj - one or more object keys to exclude from the match
|
||||||
"""
|
"""
|
||||||
exclude_restriction = excludeobj and Q(pk__in=[_GA(obj, "in") for obj in make_iter(excludeobj)]) or Q()
|
exclude_restriction = Q(pk__in=[_GA(obj, "id") for obj in make_iter(excludeobj)]) if excludeobj else Q()
|
||||||
return self.filter(db_location=location).exclude(exclude_restriction)
|
return self.filter(db_location=location).exclude(exclude_restriction)
|
||||||
|
|
||||||
@returns_typeclass_list
|
@returns_typeclass_list
|
||||||
|
|
|
||||||
|
|
@ -145,265 +145,14 @@ class ObjectDB(TypedObject):
|
||||||
_SA(self, "aliases", AliasHandler(self, category_prefix="object_"))
|
_SA(self, "aliases", AliasHandler(self, category_prefix="object_"))
|
||||||
_SA(self, "nicks", NickHandler(self))
|
_SA(self, "nicks", NickHandler(self))
|
||||||
# make sure to sync the contents cache when initializing
|
# make sure to sync the contents cache when initializing
|
||||||
_GA(self, "contents_update")()
|
#_GA(self, "contents_update")()
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
def _at_db_player_presave(self):
|
||||||
# @property decorators that allows to access these fields using
|
|
||||||
# normal python operations (without having to remember to save()
|
|
||||||
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
|
||||||
# defined that allows the user to do self.attr = value,
|
|
||||||
# value = self.attr and del self.attr respectively (where self
|
|
||||||
# is the object in question).
|
|
||||||
|
|
||||||
|
|
||||||
## player property (wraps db_player)
|
|
||||||
##@property
|
|
||||||
#def __player_get(self):
|
|
||||||
# """
|
|
||||||
# Getter. Allows for value = self.player.
|
|
||||||
# We have to be careful here since Player is also
|
|
||||||
# a TypedObject, so as to not create a loop.
|
|
||||||
# """
|
|
||||||
# player = _GA(self, "db_player")
|
|
||||||
# #player = get_field_cache(self, "player")
|
|
||||||
# if player:
|
|
||||||
# try:
|
|
||||||
# return player.typeclass
|
|
||||||
# except Exception,e:
|
|
||||||
# print "player_get:", e
|
|
||||||
# return player
|
|
||||||
|
|
||||||
##@player.setter
|
|
||||||
#def __player_set(self, player):
|
|
||||||
# "Setter. Allows for self.player = value"
|
|
||||||
# if inherits_from(player, TypeClass):
|
|
||||||
# player = player.dbobj
|
|
||||||
# _SA(self, "db_player", player)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# #set_field_cache(self, "player", player)
|
|
||||||
# # we must set this here or superusers won't be able to
|
|
||||||
# # bypass lockchecks unless they start the game connected
|
|
||||||
# # to the character in question.
|
|
||||||
# self.locks.cache_lock_bypass(self)
|
|
||||||
|
|
||||||
##@player.deleter
|
|
||||||
#def __player_del(self):
|
|
||||||
# "Deleter. Allows for del self.player"
|
|
||||||
# _SA(self, "db_player", None)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# #del_field_cache(self, "player")
|
|
||||||
#player = property(__player_get, __player_set, __player_del)
|
|
||||||
|
|
||||||
#sessid property (wraps db_sessid)
|
|
||||||
#@property
|
|
||||||
#def __sessid_get(self):
|
|
||||||
# """
|
|
||||||
# Getter. Allows for value = self.sessid. Since sessid
|
|
||||||
# is directly related to self.player, we cannot have
|
|
||||||
# a sessid without a player being connected (but the
|
|
||||||
# opposite could be true).
|
|
||||||
# """
|
|
||||||
# return _GA(self, "db_sessid")
|
|
||||||
# #if not get_field_cache(self, "sessid"):
|
|
||||||
# # del_field_cache(self, "sessid")
|
|
||||||
# #return get_field_cache(self, "sessid")
|
|
||||||
##@sessid.setter
|
|
||||||
#def __sessid_set(self, sessid):
|
|
||||||
# "Setter. Allows for self.player = value"
|
|
||||||
# _SA(self, "db_sessid", sessid)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# #set_field_cache(self, "sessid", sessid)
|
|
||||||
##@sessid.deleter
|
|
||||||
#def __sessid_del(self):
|
|
||||||
# "Deleter. Allows for del self.player"
|
|
||||||
# _SA(self, "db_sessid", None)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# #del_field_cache(self, "sessid")
|
|
||||||
#sessid = property(__sessid_get, __sessid_set, __sessid_del)
|
|
||||||
|
|
||||||
def _at_db_player_save(self, new_value, old_value=None):
|
|
||||||
"""
|
"""
|
||||||
This is called automatically just before a new player is saved.
|
This hook is called automatically just before the player field is saved.
|
||||||
"""
|
"""
|
||||||
# we need to re-cache this for superusers to bypass.
|
# we need to re-cache this for superusers to bypass.
|
||||||
self.locks.cache_lock_bypass(self)
|
self.locks.cache_lock_bypass(self)
|
||||||
return new_value
|
|
||||||
|
|
||||||
def _at_db_location_save(self, new_value, old_value=None):
|
|
||||||
"""
|
|
||||||
This is called automatically just before a new location is saved.
|
|
||||||
"""
|
|
||||||
loc = new_value
|
|
||||||
try:
|
|
||||||
old_loc = old_value
|
|
||||||
# recursive location check
|
|
||||||
def is_loc_loop(loc, depth=0):
|
|
||||||
"Recursively traverse the target location to make sure we are not in it."
|
|
||||||
if depth > 10: return
|
|
||||||
elif loc == self: raise RuntimeError
|
|
||||||
elif loc == None: raise RuntimeWarning # just to quickly get out
|
|
||||||
return is_loc_loop(_GA(loc, "db_location"), depth+1)
|
|
||||||
# check so we don't create a location loop - if so, RuntimeError will be raised.
|
|
||||||
try: is_loc_loop(loc)
|
|
||||||
except RuntimeWarning: pass
|
|
||||||
|
|
||||||
# update the contents of each location
|
|
||||||
if old_loc:
|
|
||||||
_GA(_GA(old_loc, "dbobj"), "contents_update")()
|
|
||||||
#print "after contents_update for old_loc:", old_loc.key, old_loc.contents
|
|
||||||
if loc:
|
|
||||||
_GA(_GA(loc, "dbobj"), "contents_update")()
|
|
||||||
#print "after contents_update for loc:", loc.key, loc.contents
|
|
||||||
return loc
|
|
||||||
except RuntimeError:
|
|
||||||
string = "Cannot set location, "
|
|
||||||
string += "%s.location = %s would create a location-loop." % (self.key, loc)
|
|
||||||
_GA(self, "msg")(_(string))
|
|
||||||
logger.log_trace(string)
|
|
||||||
raise RuntimeError(string)
|
|
||||||
except Exception, e:
|
|
||||||
string = "Cannot set location (%s): " % str(e)
|
|
||||||
string += "%s is not a valid location." % loc
|
|
||||||
_GA(self, "msg")(_(string))
|
|
||||||
logger.log_trace(string)
|
|
||||||
raise Exception(string)
|
|
||||||
|
|
||||||
## location property (wraps db_location)
|
|
||||||
##@property
|
|
||||||
#def __location_get(self):
|
|
||||||
# "Getter. Allows for value = self.location."
|
|
||||||
# loc = get_field_cache(self, "location")
|
|
||||||
# if loc:
|
|
||||||
# return _GA(loc, "typeclass")
|
|
||||||
# return None
|
|
||||||
##@location.setter
|
|
||||||
#def __location_set(self, location):
|
|
||||||
# "Setter. Allows for self.location = location"
|
|
||||||
# try:
|
|
||||||
# old_loc = _GA(self, "location")
|
|
||||||
# if ObjectDB.objects.dbref(location):
|
|
||||||
# # dbref search
|
|
||||||
# loc = ObjectDB.objects.dbref_search(location)
|
|
||||||
# loc = loc and _GA(loc, "dbobj")
|
|
||||||
# elif location and type(location) != ObjectDB:
|
|
||||||
# loc = _GA(location, "dbobj")
|
|
||||||
# else:
|
|
||||||
# loc = location
|
|
||||||
|
|
||||||
# # recursive location check
|
|
||||||
# def is_loc_loop(loc, depth=0):
|
|
||||||
# "Recursively traverse the target location to make sure we are not in it."
|
|
||||||
# if depth > 10: return
|
|
||||||
# elif loc == self: raise RuntimeError
|
|
||||||
# elif loc == None: raise RuntimeWarning # just to quickly get out
|
|
||||||
# return is_loc_loop(_GA(loc, "db_location"), depth+1)
|
|
||||||
# # check so we don't create a location loop - if so, RuntimeError will be raised.
|
|
||||||
# try: is_loc_loop(loc)
|
|
||||||
# except RuntimeWarning: pass
|
|
||||||
|
|
||||||
# # set the location
|
|
||||||
# set_field_cache(self, "location", loc)
|
|
||||||
# # update the contents of each location
|
|
||||||
# if old_loc:
|
|
||||||
# _GA(_GA(old_loc, "dbobj"), "contents_update")()
|
|
||||||
# if loc:
|
|
||||||
# _GA(loc, "contents_update")()
|
|
||||||
# except RuntimeError:
|
|
||||||
# string = "Cannot set location, "
|
|
||||||
# string += "%s.location = %s would create a location-loop." % (self.key, loc)
|
|
||||||
# _GA(self, "msg")(_(string))
|
|
||||||
# logger.log_trace(string)
|
|
||||||
# raise RuntimeError(string)
|
|
||||||
# except Exception, e:
|
|
||||||
# string = "Cannot set location (%s): " % str(e)
|
|
||||||
# string += "%s is not a valid location." % location
|
|
||||||
# _GA(self, "msg")(_(string))
|
|
||||||
# logger.log_trace(string)
|
|
||||||
# raise Exception(string)
|
|
||||||
##@location.deleter
|
|
||||||
#def __location_del(self):
|
|
||||||
# "Deleter. Allows for del self.location"
|
|
||||||
# _GA(self, "location").contents_update()
|
|
||||||
# _SA(self, "db_location", None)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# del_field_cache(self, "location")
|
|
||||||
#location = property(__location_get, __location_set, __location_del)
|
|
||||||
|
|
||||||
# home property (wraps db_home)
|
|
||||||
#@property
|
|
||||||
#def __home_get(self):
|
|
||||||
# "Getter. Allows for value = self.home"
|
|
||||||
# home = get_field_cache(self, "home")
|
|
||||||
# if home:
|
|
||||||
# return _GA(home, "typeclass")
|
|
||||||
# return None
|
|
||||||
##@home.setter
|
|
||||||
#def __home_set(self, home):
|
|
||||||
# "Setter. Allows for self.home = value"
|
|
||||||
# try:
|
|
||||||
# if home == None or type(home) == ObjectDB:
|
|
||||||
# hom = home
|
|
||||||
# elif ObjectDB.objects.dbref(home):
|
|
||||||
# hom = ObjectDB.objects.dbref_search(home)
|
|
||||||
# if hom and hasattr(hom,'dbobj'):
|
|
||||||
# hom = _GA(hom, "dbobj")
|
|
||||||
# else:
|
|
||||||
# hom = _GA(home, "dbobj")
|
|
||||||
# else:
|
|
||||||
# hom = _GA(home, "dbobj")
|
|
||||||
# set_field_cache(self, "home", hom)
|
|
||||||
# except Exception:
|
|
||||||
# string = "Cannot set home: "
|
|
||||||
# string += "%s is not a valid home."
|
|
||||||
# _GA(self, "msg")(_(string) % home)
|
|
||||||
# logger.log_trace(string)
|
|
||||||
# #raise
|
|
||||||
##@home.deleter
|
|
||||||
#def __home_del(self):
|
|
||||||
# "Deleter. Allows for del self.home."
|
|
||||||
# _SA(self, "db_home", None)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# del_field_cache(self, "home")
|
|
||||||
#home = property(__home_get, __home_set, __home_del)
|
|
||||||
|
|
||||||
# destination property (wraps db_destination)
|
|
||||||
#@property
|
|
||||||
#def __destination_get(self):
|
|
||||||
# "Getter. Allows for value = self.destination."
|
|
||||||
# dest = get_field_cache(self, "destination")
|
|
||||||
# if dest:
|
|
||||||
# return _GA(dest, "typeclass")
|
|
||||||
# return None
|
|
||||||
##@destination.setter
|
|
||||||
#def __destination_set(self, destination):
|
|
||||||
# "Setter. Allows for self.destination = destination"
|
|
||||||
# try:
|
|
||||||
# if destination == None or type(destination) == ObjectDB:
|
|
||||||
# # destination is None or a valid object
|
|
||||||
# dest = destination
|
|
||||||
# elif ObjectDB.objects.dbref(destination):
|
|
||||||
# # destination is a dbref; search
|
|
||||||
# dest = ObjectDB.objects.dbref_search(destination)
|
|
||||||
# if dest and _GA(self, "_hasattr")(dest,'dbobj'):
|
|
||||||
# dest = _GA(dest, "dbobj")
|
|
||||||
# else:
|
|
||||||
# dest = _GA(destination, "dbobj")
|
|
||||||
# else:
|
|
||||||
# dest = destination.dbobj
|
|
||||||
# set_field_cache(self, "destination", dest)
|
|
||||||
# except Exception:
|
|
||||||
# string = "Cannot set destination: "
|
|
||||||
# string += "%s is not a valid destination." % destination
|
|
||||||
# _GA(self, "msg")(string)
|
|
||||||
# logger.log_trace(string)
|
|
||||||
# raise
|
|
||||||
##@destination.deleter
|
|
||||||
#def __destination_del(self):
|
|
||||||
# "Deleter. Allows for del self.destination"
|
|
||||||
# _SA(self, "db_destination", None)
|
|
||||||
# _GA(self, "save")()
|
|
||||||
# del_field_cache(self, "destination")
|
|
||||||
#destination = property(__destination_get, __destination_set, __destination_del)
|
|
||||||
|
|
||||||
# cmdset_storage property. We use a custom wrapper to manage this. This also
|
# cmdset_storage property. We use a custom wrapper to manage this. This also
|
||||||
# seems very sensitive to caching, so leaving it be for now. /Griatch
|
# seems very sensitive to caching, so leaving it be for now. /Griatch
|
||||||
|
|
@ -434,7 +183,6 @@ class ObjectDB(TypedObject):
|
||||||
# ObjectDB class access methods/properties
|
# ObjectDB class access methods/properties
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def __sessions_get(self):
|
def __sessions_get(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -473,23 +221,11 @@ class ObjectDB(TypedObject):
|
||||||
|
|
||||||
exclude is one or more objects to not return
|
exclude is one or more objects to not return
|
||||||
"""
|
"""
|
||||||
contents = get_prop_cache(self, "_contents")
|
|
||||||
if contents == None:
|
|
||||||
# this is the case if this is the first call
|
|
||||||
contents = _GA(self, "contents_update")()
|
|
||||||
if exclude:
|
if exclude:
|
||||||
exclude = [obj.typeclass for obj in make_iter(exclude)]
|
return ObjectDB.objects.get_contents(self, excludeobj=exclude)
|
||||||
return [obj for obj in contents if obj not in exclude]
|
return ObjectDB.objects.get_contents(self)
|
||||||
else:
|
|
||||||
return contents
|
|
||||||
contents = property(contents_get)
|
contents = property(contents_get)
|
||||||
|
|
||||||
def contents_update(self):
|
|
||||||
"Re-sync the contents cache"
|
|
||||||
contents = ObjectDB.objects.get_contents(self)
|
|
||||||
set_prop_cache(self, "_contents", contents)
|
|
||||||
return contents
|
|
||||||
|
|
||||||
#@property
|
#@property
|
||||||
def __exits_get(self):
|
def __exits_get(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -972,6 +708,6 @@ class ObjectDB(TypedObject):
|
||||||
# Perform the deletion of the object
|
# Perform the deletion of the object
|
||||||
super(ObjectDB, self).delete()
|
super(ObjectDB, self).delete()
|
||||||
# clear object's old location's content cache of this object
|
# clear object's old location's content cache of this object
|
||||||
if old_loc:
|
#if old_loc:
|
||||||
_GA(old_loc.dbobj, "contents_update")()
|
# _GA(old_loc.dbobj, "contents_update")()
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
|
|
@ -117,29 +117,11 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
_SA(self, "aliases", AliasHandler(self, category_prefix="player_"))
|
_SA(self, "aliases", AliasHandler(self, category_prefix="player_"))
|
||||||
_SA(self, "nicks", NickHandler(self))
|
_SA(self, "nicks", NickHandler(self))
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
# alias to the objs property
|
||||||
# @property decorators that allows to access these fields using
|
def __characters_get(self): return self.objs
|
||||||
# normal python operations (without having to remember to save()
|
def __characters_set(self, value): self.objs = value
|
||||||
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
def __characters_del(self): raise Exception("Cannot delete name")
|
||||||
# defined that allows the user to do self.attr = value,
|
characters = property(__characters_get, __characters_set, __characters_del)
|
||||||
# value = self.attr and del self.attr respectively (where self
|
|
||||||
# is the object in question).
|
|
||||||
|
|
||||||
# obj property (wraps db_obj)
|
|
||||||
#@property
|
|
||||||
def objs_get(self):
|
|
||||||
"Getter. Allows for value = self.obj"
|
|
||||||
return list(self.db_objs.all())
|
|
||||||
#@objs.setter
|
|
||||||
def objs_set(self, value):
|
|
||||||
"Setter. Allows for self.objs = value"
|
|
||||||
raise Exception("Use access methods to add new characters instead.")
|
|
||||||
#@obj.deleter
|
|
||||||
def objs_del(self):
|
|
||||||
"Deleter. Allows for del self.obj"
|
|
||||||
raise Exception("Use access methods to delete new characters instead.")
|
|
||||||
objs = property(objs_get, objs_set, objs_del)
|
|
||||||
characters = property(objs_get, objs_set, objs_del)
|
|
||||||
|
|
||||||
# cmdset_storage property
|
# cmdset_storage property
|
||||||
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
||||||
|
|
@ -161,20 +143,6 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
_GA(self, "save")()
|
_GA(self, "save")()
|
||||||
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
cmdset_storage = property(cmdset_storage_get, cmdset_storage_set, cmdset_storage_del)
|
||||||
|
|
||||||
##@property
|
|
||||||
#def is_connected_get(self):
|
|
||||||
# "Getter. Allows for value = self.is_connected"
|
|
||||||
# return get_field_cache(self, "is_connected")
|
|
||||||
##@is_connected.setter
|
|
||||||
#def is_connected_set(self, value):
|
|
||||||
# "Setter. Allows for self.is_connected = value"
|
|
||||||
# set_field_cache(self, "is_connected", value)
|
|
||||||
##@is_connected.deleter
|
|
||||||
#def is_connected_del(self):
|
|
||||||
# "Deleter. Allows for del is_connected"
|
|
||||||
# set_field_cache(self, "is_connected", False)
|
|
||||||
#is_connected = property(is_connected_get, is_connected_set, is_connected_del)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
verbose_name = "Player"
|
verbose_name = "Player"
|
||||||
|
|
@ -190,35 +158,14 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u"%s(player#%s)" % (_GA(self, "name"), _GA(self, "dbid"))
|
return u"%s(player#%s)" % (_GA(self, "name"), _GA(self, "dbid"))
|
||||||
|
|
||||||
|
|
||||||
# name property (wraps self.user.username)
|
|
||||||
#@property
|
#@property
|
||||||
#def __name_get(self):
|
|
||||||
# "Getter. Allows for value = self.name"
|
|
||||||
# return self.username
|
|
||||||
# #name = get_prop_cache(self, "_name")
|
|
||||||
# #if not name:
|
|
||||||
# # name = _GA(self,"user").username
|
|
||||||
# # set_prop_cache(self, "_name", name)
|
|
||||||
# #return name
|
|
||||||
##@name.setter
|
|
||||||
#def __name_set(self, value):
|
|
||||||
# "Setter. Allows for player.name = newname"
|
|
||||||
# _SA(self, "username", value)
|
|
||||||
|
|
||||||
# #_GA(self, "user").username = value
|
|
||||||
# #_GA(self, "user").save()
|
|
||||||
# #set_prop_cache(self, "_name", value)
|
|
||||||
##@name.deleter
|
|
||||||
#def __name_del(self):
|
|
||||||
# "Deleter. Allows for del self.name"
|
|
||||||
# raise Exception("Player name cannot be deleted!")
|
|
||||||
def __username_get(self):
|
def __username_get(self):
|
||||||
return _GA(self, "username")
|
return _GA(self, "username")
|
||||||
def __username_set(self, value):
|
def __username_set(self, value):
|
||||||
_SA(self, "username", value)
|
_SA(self, "username", value)
|
||||||
def __username_del(self):
|
def __username_del(self):
|
||||||
_DA(self, "username", value)
|
_DA(self, "username", value)
|
||||||
|
# aliases
|
||||||
name = property(__username_get, __username_set, __username_del)
|
name = property(__username_get, __username_set, __username_del)
|
||||||
key = property(__username_get, __username_set, __username_del)
|
key = property(__username_get, __username_set, __username_del)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,133 +111,6 @@ class ScriptDB(TypedObject):
|
||||||
_SA(self, "attributes", AttributeHandler(self))
|
_SA(self, "attributes", AttributeHandler(self))
|
||||||
#_SA(self, "aliases", AliasHandler(self, category_prefix="script_"))
|
#_SA(self, "aliases", AliasHandler(self, category_prefix="script_"))
|
||||||
|
|
||||||
# Wrapper properties to easily set database fields. These are
|
|
||||||
# @property decorators that allows to access these fields using
|
|
||||||
# normal python operations (without having to remember to save()
|
|
||||||
# etc). So e.g. a property 'attr' has a get/set/del decorator
|
|
||||||
# defined that allows the user to do self.attr = value,
|
|
||||||
# value = self.attr and del self.attr respectively (where self
|
|
||||||
# is the script in question).
|
|
||||||
|
|
||||||
# desc property (wraps db_desc)
|
|
||||||
#@property
|
|
||||||
#def __desc_get(self):
|
|
||||||
# "Getter. Allows for value = self.desc"
|
|
||||||
# return self.db_desc
|
|
||||||
##@desc.setter
|
|
||||||
#def __desc_set(self, value):
|
|
||||||
# "Setter. Allows for self.desc = value"
|
|
||||||
# self.db_desc = value
|
|
||||||
# self.save()
|
|
||||||
##@desc.deleter
|
|
||||||
#def __desc_del(self):
|
|
||||||
# "Deleter. Allows for del self.desc"
|
|
||||||
# self.db_desc = ""
|
|
||||||
# self.save()
|
|
||||||
#desc = property(__desc_get, __desc_set, __desc_del)
|
|
||||||
|
|
||||||
# obj property (wraps db_obj)
|
|
||||||
#@property
|
|
||||||
#def __obj_get(self):
|
|
||||||
# "Getter. Allows for value = self.obj"
|
|
||||||
# return self.db_obj
|
|
||||||
##@obj.setter
|
|
||||||
#def __obj_set(self, value):
|
|
||||||
# "Setter. Allows for self.obj = value"
|
|
||||||
# self.db_obj = value
|
|
||||||
# self.save()
|
|
||||||
##@obj.deleter
|
|
||||||
#def __obj_del(self):
|
|
||||||
# "Deleter. Allows for del self.obj"
|
|
||||||
# self.db_obj = None
|
|
||||||
# self.save()
|
|
||||||
#obj = property(__obj_get, __obj_set, __obj_del)
|
|
||||||
|
|
||||||
# interval property (wraps db_interval)
|
|
||||||
#@property
|
|
||||||
#def __interval_get(self):
|
|
||||||
# "Getter. Allows for value = self.interval"
|
|
||||||
# return self.db_interval
|
|
||||||
##@interval.setter
|
|
||||||
#def __interval_set(self, value):
|
|
||||||
# "Setter. Allows for self.interval = value"
|
|
||||||
# self.db_interval = int(value)
|
|
||||||
# self.save()
|
|
||||||
##@interval.deleter
|
|
||||||
#def __interval_del(self):
|
|
||||||
# "Deleter. Allows for del self.interval"
|
|
||||||
# self.db_interval = 0
|
|
||||||
# self.save()
|
|
||||||
#interval = property(__interval_get, __interval_set, __interval_del)
|
|
||||||
|
|
||||||
# start_delay property (wraps db_start_delay)
|
|
||||||
#@property
|
|
||||||
#def __start_delay_get(self):
|
|
||||||
# "Getter. Allows for value = self.start_delay"
|
|
||||||
# return self.db_start_delay
|
|
||||||
##@start_delay.setter
|
|
||||||
#def __start_delay_set(self, value):
|
|
||||||
# "Setter. Allows for self.start_delay = value"
|
|
||||||
# self.db_start_delay = value
|
|
||||||
# self.save()
|
|
||||||
##@start_delay.deleter
|
|
||||||
#def __start_delay_del(self):
|
|
||||||
# "Deleter. Allows for del self.start_delay"
|
|
||||||
# self.db_start_delay = False
|
|
||||||
# self.save()
|
|
||||||
#start_delay = property(__start_delay_get, __start_delay_set, __start_delay_del)
|
|
||||||
|
|
||||||
# repeats property (wraps db_repeats)
|
|
||||||
#@property
|
|
||||||
#def __repeats_get(self):
|
|
||||||
# "Getter. Allows for value = self.repeats"
|
|
||||||
# return self.db_repeats
|
|
||||||
##@repeats.setter
|
|
||||||
#def __repeats_set(self, value):
|
|
||||||
# "Setter. Allows for self.repeats = value"
|
|
||||||
# self.db_repeats = int(value)
|
|
||||||
# self.save()
|
|
||||||
##@repeats.deleter
|
|
||||||
#def __repeats_del(self):
|
|
||||||
# "Deleter. Allows for del self.repeats"
|
|
||||||
# self.db_repeats = 0
|
|
||||||
# self.save()
|
|
||||||
#repeats = property(__repeats_get, __repeats_set, __repeats_del)
|
|
||||||
|
|
||||||
# persistent property (wraps db_persistent)
|
|
||||||
#@property
|
|
||||||
#def __persistent_get(self):
|
|
||||||
# "Getter. Allows for value = self.persistent"
|
|
||||||
# return self.db_persistent
|
|
||||||
##@persistent.setter
|
|
||||||
#def __persistent_set(self, value):
|
|
||||||
# "Setter. Allows for self.persistent = value"
|
|
||||||
# self.db_persistent = value
|
|
||||||
# self.save()
|
|
||||||
##@persistent.deleter
|
|
||||||
#def __persistent_del(self):
|
|
||||||
# "Deleter. Allows for del self.persistent"
|
|
||||||
# self.db_persistent = False
|
|
||||||
# self.save()
|
|
||||||
#persistent = property(__persistent_get, __persistent_set, __persistent_del)
|
|
||||||
|
|
||||||
# is_active property (wraps db_is_active)
|
|
||||||
#@property
|
|
||||||
#def __is_active_get(self):
|
|
||||||
# "Getter. Allows for value = self.is_active"
|
|
||||||
# return self.db_is_active
|
|
||||||
##@is_active.setter
|
|
||||||
#def __is_active_set(self, value):
|
|
||||||
# "Setter. Allows for self.is_active = value"
|
|
||||||
# self.db_is_active = value
|
|
||||||
# self.save()
|
|
||||||
##@is_active.deleter
|
|
||||||
#def __is_active_del(self):
|
|
||||||
# "Deleter. Allows for del self.is_active"
|
|
||||||
# self.db_is_active = False
|
|
||||||
# self.save()
|
|
||||||
#is_active = property(__is_active_get, __is_active_set, __is_active_del)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# ScriptDB class properties
|
# ScriptDB class properties
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ from src.utils import logger, is_pypy
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
__all__ = ["Script", "DoNothing", "CheckSessions", "ValidateScripts", "ValidateChannelHandler"]
|
__all__ = ["Script", "DoNothing", "CheckSessions", "ValidateScripts", "ValidateChannelHandler"]
|
||||||
if not is_pypy:
|
|
||||||
__all__.append("ClearAttributeCache")
|
|
||||||
|
|
||||||
_SESSIONS = None
|
_SESSIONS = None
|
||||||
_ATTRIBUTE_CACHE_MAXSIZE = settings.ATTRIBUTE_CACHE_MAXSIZE # attr-cache size in MB.
|
_ATTRIBUTE_CACHE_MAXSIZE = settings.ATTRIBUTE_CACHE_MAXSIZE # attr-cache size in MB.
|
||||||
|
|
@ -451,19 +449,19 @@ class ValidateChannelHandler(Script):
|
||||||
#print "ValidateChannelHandler run."
|
#print "ValidateChannelHandler run."
|
||||||
channelhandler.CHANNELHANDLER.update()
|
channelhandler.CHANNELHANDLER.update()
|
||||||
|
|
||||||
class ClearAttributeCache(Script):
|
#class ClearAttributeCache(Script):
|
||||||
"Clear the attribute cache."
|
# "Clear the attribute cache."
|
||||||
def at_script_creation(self):
|
# def at_script_creation(self):
|
||||||
"Setup the script"
|
# "Setup the script"
|
||||||
self.key = "sys_cache_clear"
|
# self.key = "sys_cache_clear"
|
||||||
self.desc = _("Clears the Attribute Cache")
|
# self.desc = _("Clears the Attribute Cache")
|
||||||
self.interval = 3600 * 2
|
# self.interval = 3600 * 2
|
||||||
self.persistent = True
|
# self.persistent = True
|
||||||
def at_repeat(self):
|
# def at_repeat(self):
|
||||||
"called every 2 hours. Sets a max attr-cache limit to 100 MB." # enough for normal usage?
|
# "called every 2 hours. Sets a max attr-cache limit to 100 MB." # enough for normal usage?
|
||||||
if is_pypy:
|
# if is_pypy:
|
||||||
# pypy don't support get_size, so we have to skip out here.
|
# # pypy don't support get_size, so we have to skip out here.
|
||||||
return
|
# return
|
||||||
attr_cache_size, _, _ = caches.get_cache_sizes()
|
# attr_cache_size, _, _ = caches.get_cache_sizes()
|
||||||
if attr_cache_size > _ATTRIBUTE_CACHE_MAXSIZE:
|
# if attr_cache_size > _ATTRIBUTE_CACHE_MAXSIZE:
|
||||||
caches.flush_attr_cache()
|
# caches.flush_attr_cache()
|
||||||
|
|
|
||||||
|
|
@ -97,27 +97,35 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
||||||
update_fields = _GA(_GA(instance, "_meta"), "fields")
|
update_fields = _GA(_GA(instance, "_meta"), "fields")
|
||||||
for field in update_fields:
|
for field in update_fields:
|
||||||
fieldname = field.name
|
fieldname = field.name
|
||||||
new_value = _GA(instance, fieldname)#field.value_from_object(instance)
|
handlername = "_at_%s_presave" % fieldname
|
||||||
# try to see if there is a handler on object that should be triggered when saving.
|
|
||||||
handlername = "_at_%s_save" % fieldname
|
|
||||||
handler = _GA(instance, handlername) if handlername in _GA(sender, '__dict__') else None
|
handler = _GA(instance, handlername) if handlername in _GA(sender, '__dict__') else None
|
||||||
if callable(handler):
|
if callable(handler):
|
||||||
#hid = hashid(instance, "-%s" % fieldname)
|
handler()
|
||||||
try:
|
|
||||||
old_value = _GA(instance, _GA(field, "get_cache_name")())
|
def field_post_save(sender, instance=None, update_fields=None, raw=False, **kwargs):
|
||||||
except AttributeError:
|
"""
|
||||||
old_value=None
|
Called at the beginning of the field save operation. The save method
|
||||||
# the handler may modify the stored value in various ways
|
must be called with the update_fields keyword in order to be most efficient.
|
||||||
# don't catch exceptions, the handler must work!
|
This method should NOT save; rather it is the save() that triggers this function.
|
||||||
new_value = handler(new_value, old_value=old_value)
|
Its main purpose is to allow to plug-in a save handler and oob handlers.
|
||||||
# we re-assign this to the field, save() will pick it up from there
|
"""
|
||||||
_SA(instance, fieldname, new_value)
|
if raw:
|
||||||
|
return
|
||||||
|
if update_fields:
|
||||||
|
# this is a list of strings at this point. We want field objects
|
||||||
|
update_fields = (_GA(_GA(instance, "_meta"), "get_field_by_name")(field)[0] for field in update_fields)
|
||||||
|
else:
|
||||||
|
# meta.fields are already field objects; get them all
|
||||||
|
update_fields = _GA(_GA(instance, "_meta"), "fields")
|
||||||
|
for field in update_fields:
|
||||||
|
fieldname = field.name
|
||||||
|
handlername = "_at_%s_postsave" % fieldname
|
||||||
|
handler = _GA(instance, handlername) if handlername in _GA(sender, '__dict__') else None
|
||||||
|
if callable(handler):
|
||||||
|
handler()
|
||||||
trackerhandler = _GA(instance, "_trackerhandler") if "_trackerhandler" in _GA(instance, '__dict__') else None
|
trackerhandler = _GA(instance, "_trackerhandler") if "_trackerhandler" in _GA(instance, '__dict__') else None
|
||||||
if trackerhandler:
|
if trackerhandler:
|
||||||
trackerhandler.update(fieldname, new_value)
|
trackerhandler.update(fieldname, _GA(instance, fieldname))
|
||||||
#if hid:
|
|
||||||
# # update cache
|
|
||||||
# _FIELD_CACHE[hid] = new_value
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Attr cache - caching the attribute objects related to a given object to
|
# Attr cache - caching the attribute objects related to a given object to
|
||||||
|
|
@ -125,63 +133,64 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
||||||
# to any property).
|
# to any property).
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
||||||
# connected to m2m_changed signal in respective model class
|
## connected to m2m_changed signal in respective model class
|
||||||
def post_attr_update(sender, **kwargs):
|
#def post_attr_update(sender, **kwargs):
|
||||||
"Called when the many2many relation changes (NOT when updating the value of an Attribute!)"
|
# "Called when the many2many relation changes (NOT when updating the value of an Attribute!)"
|
||||||
obj = kwargs['instance']
|
# obj = kwargs['instance']
|
||||||
model = kwargs['model']
|
# model = kwargs['model']
|
||||||
action = kwargs['action']
|
# action = kwargs['action']
|
||||||
if kwargs['reverse']:
|
# if kwargs['reverse']:
|
||||||
# the reverse relation changed (the Attribute itself was acted on)
|
# # the reverse relation changed (the Attribute itself was acted on)
|
||||||
pass
|
# pass
|
||||||
else:
|
# else:
|
||||||
# forward relation changed (the Object holding the Attribute m2m field)
|
# # forward relation changed (the Object holding the Attribute m2m field)
|
||||||
if not kwargs["pk_set"]:
|
# if not kwargs["pk_set"]:
|
||||||
return
|
# return
|
||||||
if action == "post_add":
|
# if action == "post_add":
|
||||||
# cache all added objects
|
# # cache all added objects
|
||||||
for attr_id in kwargs["pk_set"]:
|
# for attr_id in kwargs["pk_set"]:
|
||||||
attr_obj = model.objects.get(pk=attr_id)
|
# attr_obj = model.objects.get(pk=attr_id)
|
||||||
set_attr_cache(obj, _GA(attr_obj, "db_key"), attr_obj)
|
# set_attr_cache(obj, _GA(attr_obj, "db_key"), attr_obj)
|
||||||
elif action == "post_remove":
|
# elif action == "post_remove":
|
||||||
# obj.db_attributes.remove(attr) was called
|
# # obj.db_attributes.remove(attr) was called
|
||||||
for attr_id in kwargs["pk_set"]:
|
# for attr_id in kwargs["pk_set"]:
|
||||||
attr_obj = model.objects.get(pk=attr_id)
|
# attr_obj = model.objects.get(pk=attr_id)
|
||||||
del_attr_cache(obj, _GA(attr_obj, "db_key"))
|
# del_attr_cache(obj, _GA(attr_obj, "db_key"))
|
||||||
attr_obj.delete()
|
# attr_obj.delete()
|
||||||
elif action == "post_clear":
|
# elif action == "post_clear":
|
||||||
# obj.db_attributes.clear() was called
|
# # obj.db_attributes.clear() was called
|
||||||
clear_obj_attr_cache(obj)
|
# clear_obj_attr_cache(obj)
|
||||||
|
#
|
||||||
# access methods
|
#
|
||||||
|
## attr cache - this is only left as deprecated cache
|
||||||
def get_attr_cache(obj, attrname):
|
#
|
||||||
"Called by getting attribute"
|
#def get_attr_cache(obj, attrname):
|
||||||
hid = hashid(obj, "-%s" % attrname)
|
# "Called by getting attribute"
|
||||||
return _ATTR_CACHE.get(hid, None)
|
# hid = hashid(obj, "-%s" % attrname)
|
||||||
|
# return _ATTR_CACHE.get(hid, None)
|
||||||
def set_attr_cache(obj, attrname, attrobj):
|
#
|
||||||
"Set the attr cache manually; this can be used to update"
|
#def set_attr_cache(obj, attrname, attrobj):
|
||||||
global _ATTR_CACHE
|
# "Set the attr cache manually; this can be used to update"
|
||||||
hid = hashid(obj, "-%s" % attrname)
|
# global _ATTR_CACHE
|
||||||
_ATTR_CACHE[hid] = attrobj
|
# hid = hashid(obj, "-%s" % attrname)
|
||||||
|
# _ATTR_CACHE[hid] = attrobj
|
||||||
def del_attr_cache(obj, attrname):
|
#
|
||||||
"Del attribute cache"
|
#def del_attr_cache(obj, attrname):
|
||||||
global _ATTR_CACHE
|
# "Del attribute cache"
|
||||||
hid = hashid(obj, "-%s" % attrname)
|
# global _ATTR_CACHE
|
||||||
if hid in _ATTR_CACHE:
|
# hid = hashid(obj, "-%s" % attrname)
|
||||||
del _ATTR_CACHE[hid]
|
# if hid in _ATTR_CACHE:
|
||||||
|
# del _ATTR_CACHE[hid]
|
||||||
def flush_attr_cache():
|
#
|
||||||
"Clear attribute cache"
|
#def flush_attr_cache():
|
||||||
global _ATTR_CACHE
|
# "Clear attribute cache"
|
||||||
_ATTR_CACHE = {}
|
# global _ATTR_CACHE
|
||||||
|
# _ATTR_CACHE = {}
|
||||||
def clear_obj_attr_cache(obj):
|
#
|
||||||
global _ATTR_CACHE
|
#def clear_obj_attr_cache(obj):
|
||||||
hid = hashid(obj)
|
# global _ATTR_CACHE
|
||||||
_ATTR_CACHE = {key:value for key, value in _ATTR_CACHE if not key.startswith(hid)}
|
# hid = hashid(obj)
|
||||||
|
# _ATTR_CACHE = {key:value for key, value in _ATTR_CACHE if not key.startswith(hid)}
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Property cache - this is a generic cache for properties stored on models.
|
# Property cache - this is a generic cache for properties stored on models.
|
||||||
|
|
|
||||||
|
|
@ -152,8 +152,8 @@ def create_system_scripts():
|
||||||
# update the channel handler to make sure it's in sync
|
# update the channel handler to make sure it's in sync
|
||||||
script3 = create.create_script(scripts.ValidateChannelHandler)
|
script3 = create.create_script(scripts.ValidateChannelHandler)
|
||||||
# clear the attribute cache regularly
|
# clear the attribute cache regularly
|
||||||
script4 = create.create_script(scripts.ClearAttributeCache)
|
#script4 = create.create_script(scripts.ClearAttributeCache)
|
||||||
if not script1 or not script2 or not script3 or not script4:
|
if not script1 or not script2 or not script3:# or not script4:
|
||||||
print " Error creating system scripts."
|
print " Error creating system scripts."
|
||||||
|
|
||||||
def start_game_time():
|
def start_game_time():
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,17 @@ from src.server.sessionhandler import SESSIONS
|
||||||
|
|
||||||
# setting up server-side field cache
|
# setting up server-side field cache
|
||||||
|
|
||||||
from django.db.models.signals import pre_save
|
from django.db.models.signals import pre_save, post_save
|
||||||
from src.server.caches import field_pre_save
|
from src.server.caches import field_pre_save
|
||||||
pre_save.connect(field_pre_save, dispatch_uid="fieldcache")
|
#pre_save.connect(field_pre_save, dispatch_uid="fieldcache")
|
||||||
|
post_save.connect(field_pre_save, dispatch_uid="fieldcache")
|
||||||
|
|
||||||
from django.db.models.signals import m2m_changed
|
|
||||||
from src.typeclasses.models import TypedObject
|
from src.typeclasses.models import TypedObject
|
||||||
from src.server.caches import post_attr_update
|
#from src.server.caches import post_attr_update
|
||||||
|
#from django.db.models.signals import m2m_changed
|
||||||
|
|
||||||
# connect to attribute cache signal
|
# connect to attribute cache signal
|
||||||
m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)
|
#m2m_changed.connect(post_attr_update, sender=TypedObject.db_attributes.through)
|
||||||
|
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ from django.utils.encoding import smart_str
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
from src.utils.idmapper.models import SharedMemoryModel
|
from src.utils.idmapper.models import SharedMemoryModel
|
||||||
from src.server.caches import get_prop_cache, set_prop_cache, flush_attr_cache
|
from src.server.caches import get_prop_cache, set_prop_cache
|
||||||
|
|
||||||
#from src.server.caches import call_ndb_hooks
|
#from src.server.caches import call_ndb_hooks
|
||||||
from src.server.models import ServerConfig
|
from src.server.models import ServerConfig
|
||||||
|
|
@ -634,99 +634,12 @@ class TypedObject(SharedMemoryModel):
|
||||||
# value = self.attr and del self.attr respectively (where self
|
# value = self.attr and del self.attr respectively (where self
|
||||||
# is the object in question).
|
# is the object in question).
|
||||||
|
|
||||||
# key property (wraps db_key)
|
|
||||||
#@property
|
|
||||||
#def __key_get(self):
|
|
||||||
# "Getter. Allows for value = self.key"
|
|
||||||
# #return _GA(self, "db_key")
|
|
||||||
# return get_field_cache(self, "key")
|
|
||||||
##@key.setter
|
|
||||||
#def __key_set(self, value):
|
|
||||||
# "Setter. Allows for self.key = value"
|
|
||||||
# set_field_cache(self, "key", value)
|
|
||||||
##@key.deleter
|
|
||||||
#def __key_del(self):
|
|
||||||
# "Deleter. Allows for del self.key"
|
|
||||||
# raise Exception("Cannot delete objectdb key!")
|
|
||||||
#key = property(__key_get, __key_set, __key_del)
|
|
||||||
|
|
||||||
# name property (alias to self.key)
|
# name property (alias to self.key)
|
||||||
def __name_get(self): return self.key
|
def __name_get(self): return self.key
|
||||||
def __name_set(self, value): self.key = value
|
def __name_set(self, value): self.key = value
|
||||||
def __name_del(self): raise Exception("Cannot delete name")
|
def __name_del(self): raise Exception("Cannot delete name")
|
||||||
name = property(__name_get, __name_set, __name_del)
|
name = property(__name_get, __name_set, __name_del)
|
||||||
|
|
||||||
# typeclass_path property - we manage this separately.
|
|
||||||
#@property
|
|
||||||
#def __typeclass_path_get(self):
|
|
||||||
# "Getter. Allows for value = self.typeclass_path"
|
|
||||||
# return _GA(self, "db_typeclass_path")
|
|
||||||
##@typeclass_path.setter
|
|
||||||
#def __typeclass_path_set(self, value):
|
|
||||||
# "Setter. Allows for self.typeclass_path = value"
|
|
||||||
# _SA(self, "db_typeclass_path", value)
|
|
||||||
# update_fields = ["db_typeclass_path"] if _GA(self, "_get_pk_val")(_GA(self, "_meta")) is not None else None
|
|
||||||
# _GA(self, "save")(update_fields=update_fields)
|
|
||||||
##@typeclass_path.deleter
|
|
||||||
#def __typeclass_path_del(self):
|
|
||||||
# "Deleter. Allows for del self.typeclass_path"
|
|
||||||
# self.db_typeclass_path = ""
|
|
||||||
# _GA(self, "save")(update_fields=["db_typeclass_path"])
|
|
||||||
#typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del)
|
|
||||||
|
|
||||||
# date_created property
|
|
||||||
#@property
|
|
||||||
#def __date_created_get(self):
|
|
||||||
# "Getter. Allows for value = self.date_created"
|
|
||||||
# return get_field_cache(self, "date_created")
|
|
||||||
##@date_created.setter
|
|
||||||
#def __date_created_set(self, value):
|
|
||||||
# "Setter. Allows for self.date_created = value"
|
|
||||||
# raise Exception("Cannot change date_created!")
|
|
||||||
##@date_created.deleter
|
|
||||||
#def __date_created_del(self):
|
|
||||||
# "Deleter. Allows for del self.date_created"
|
|
||||||
# raise Exception("Cannot delete date_created!")
|
|
||||||
#date_created = property(__date_created_get, __date_created_set, __date_created_del)
|
|
||||||
|
|
||||||
# permissions property
|
|
||||||
#@property
|
|
||||||
#def __permissions_get(self):
|
|
||||||
# "Getter. Allows for value = self.name. Returns a list of permissions."
|
|
||||||
# perms = get_field_cache(self, "permissions")
|
|
||||||
# if perms:
|
|
||||||
# return [perm.strip() for perm in perms.split(',')]
|
|
||||||
# return []
|
|
||||||
##@permissions.setter
|
|
||||||
#def __permissions_set(self, value):
|
|
||||||
# "Setter. Allows for self.name = value. Stores as a comma-separated string."
|
|
||||||
# value = ",".join([utils.to_unicode(val).strip() for val in make_iter(value)])
|
|
||||||
# set_field_cache(self, "permissions", value)
|
|
||||||
##@permissions.deleter
|
|
||||||
#def __permissions_del(self):
|
|
||||||
# "Deleter. Allows for del self.name"
|
|
||||||
# self.db_permissions = ""
|
|
||||||
# self.save()
|
|
||||||
# del_field_cache(self, "permissions")
|
|
||||||
#permissions = property(__permissions_get, __permissions_set, __permissions_del)
|
|
||||||
|
|
||||||
# lock_storage property (wraps db_lock_storage)
|
|
||||||
#@property
|
|
||||||
#def __lock_storage_get(self):
|
|
||||||
# "Getter. Allows for value = self.lock_storage"
|
|
||||||
# return get_field_cache(self, "lock_storage")
|
|
||||||
##@lock_storage.setter
|
|
||||||
#def __lock_storage_set(self, value):
|
|
||||||
# """Saves the lock_storage. This is usually not called directly, but through self.lock()"""
|
|
||||||
# set_field_cache(self, "lock_storage", value)
|
|
||||||
##@lock_storage.deleter
|
|
||||||
#def __lock_storage_del(self):
|
|
||||||
# "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
|
|
||||||
# logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
|
|
||||||
#lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# TypedObject main class methods and properties
|
# TypedObject main class methods and properties
|
||||||
|
|
@ -1000,14 +913,12 @@ class TypedObject(SharedMemoryModel):
|
||||||
"""
|
"""
|
||||||
Type-level cleanup
|
Type-level cleanup
|
||||||
"""
|
"""
|
||||||
flush_attr_cache()
|
|
||||||
super(TypedObject, self).delete(*args, **kwargs)
|
super(TypedObject, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Object manipulation methods
|
# Object manipulation methods
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
def swap_typeclass(self, new_typeclass, clean_attributes=False, no_default=True):
|
def swap_typeclass(self, new_typeclass, clean_attributes=False, no_default=True):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1230,16 +1141,12 @@ class TypedObject(SharedMemoryModel):
|
||||||
raise Exception("Cannot delete the ndb object!")
|
raise Exception("Cannot delete the ndb object!")
|
||||||
ndb = property(__ndb_get, __ndb_set, __ndb_del)
|
ndb = property(__ndb_get, __ndb_set, __ndb_del)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ***** DEPRECATED METHODS BELOW *******
|
# ***** DEPRECATED METHODS BELOW *******
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Fully attr_obj attributes. You usually access these
|
# Full attr_obj attributes. You usually access these
|
||||||
# through the obj.db.attrname method.
|
# through the obj.db.attrname method.
|
||||||
|
|
||||||
# Helper methods for attr_obj attributes
|
# Helper methods for attr_obj attributes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue