예제 #1
0
	def __init__(self, cache=None):
		# {(InstanceInfo(instance).model_info.model, instance.pk): InstanceInfo, ...}}
		self._alive = WeakValueDictionary()

		# {InstanceInfo(instance): instance, ...}}
		self._dirty = {}

		if cache is not None:
			self._cache = cache
		else:
			self._cache = MRUCache(settings.MAX_CACHE)

		signals.register(
			(
				"instance-deleted",
	
				"start-tracking-changes",
				"stop-tracking-changes",
	
				"model-pre-init",
				"model-post-init",
				"model-pre-save",
				"model-post-save",
				"model-pre-delete",
				"model-post-delete",
				"model-pre-update",
				"model-post-update",
				
				# "model-history-reset",
				# "model-history-redo",
				# "model-history-undo",
				
				"relation-pre-get",
				"relation-post-get",
				"relation-pre-set",
				"relation-post-set",
				"relation-pre-delete",
				"relation-post-delete",
				"relation-pre-add",
				"relation-post-add",
				"relation-pre-remove",
				"relation-post-remove",

				"model-do-cache",
				"model-do-not-cache",
			),
			self
		)
		signals.register_with_callback("cache-rollback", self, "rollback")
예제 #2
0
class Storage(object):
	def __init__(self, cache=None):
		# {(InstanceInfo(instance).model_info.model, instance.pk): InstanceInfo, ...}}
		self._alive = WeakValueDictionary()

		# {InstanceInfo(instance): instance, ...}}
		self._dirty = {}

		if cache is not None:
			self._cache = cache
		else:
			self._cache = MRUCache(settings.MAX_CACHE)

		signals.register(
			(
				"instance-deleted",
	
				"start-tracking-changes",
				"stop-tracking-changes",
	
				"model-pre-init",
				"model-post-init",
				"model-pre-save",
				"model-post-save",
				"model-pre-delete",
				"model-post-delete",
				"model-pre-update",
				"model-post-update",
				
				# "model-history-reset",
				# "model-history-redo",
				# "model-history-undo",
				
				"relation-pre-get",
				"relation-post-get",
				"relation-pre-set",
				"relation-post-set",
				"relation-pre-delete",
				"relation-post-delete",
				"relation-pre-add",
				"relation-post-add",
				"relation-pre-remove",
				"relation-post-remove",

				"model-do-cache",
				"model-do-not-cache",
			),
			self
		)
		signals.register_with_callback("cache-rollback", self, "rollback")

	def get(self, query):
		return QuerySetIterator(query, self)

	def clear(self):
		self._dirty.clear()
		self._alive.clear()
		self._cache.clear()

	def set_dirty(self, inst_info):
		self._dirty[inst_info] = inst_info.get_inst()

	def cache(self, inf):
		self._alive.pop((inf.model_info.model, inf._lazypkval), None)
		self._alive[(inf.model_info.model, inf.get_pk_as_key())] = inf
		self._cache.add(inf)

	def uncache(self, inf):
		if inf in self._cache:
			self._cache.remove(inf)

		self._dirty.pop(inf, None)
		self._alive.pop((inf.model_info.model, inf.get_pk_as_key()), None)
		self._alive.pop((inf.model_info.model, inf._lazypkval), None)

	### signals ###

	#??? what is this used for?
	def instance_deleted(self, inst_info):
		print "instance_deleted", inst_info

	def model_pre_init(self, instance, **kwargs):
		signals.fire("stop-tracking-changes", instance=instance)

	def model_post_init(self, instance, **kwargs):
		inf = get_inst_info(instance)
		signals.fire("start-tracking-changes", instance=instance)
		self._alive[(inf.model_info.model, inf.get_pk_as_key())] = inf

		# If instance was not initialized with a value for primary key,
		# then it has not been saved yet and goes into self._dirty.
		if instance.pk is None:
			self.set_dirty(inf)

	def start_tracking_changes(self, instance):
		get_inst_info(instance)._meta["track-changes"] = True

	def stop_tracking_changes(self, instance):
		get_inst_info(instance)._meta["track-changes"] = False

	def model_pre_save(self, instance):
		pass

	def model_post_save(self, instance, created):
		inf = get_inst_info(instance)
		if not inf._meta["do-cache"]:
			return

		self.cache(inf)
		self._dirty.pop(inf, None)

		# On calling Model.delete, tracking of changes is stopped, so start
		# tracking now.
		signals.fire("start-tracking-changes", instance=instance)

	def model_pre_update(self, instance, value, fieldname):
		# instance._inst_info.record_change(fieldname, value)
		pass

	def model_post_update(self, instance, value, fieldname):
		inf = get_inst_info(instance)

		if not inf in self._dirty:
			self.set_dirty(inf)

	def model_pre_delete(self, instance):
		signals.fire("stop-tracking-changes", instance=instance)

	def model_post_delete(self, instance, deleted):
		if not deleted:
			return

		inf = get_inst_info(instance)

		self.uncache(inf)

		instance.id = None

	def model_do_cache(self, instance):
		inf = get_inst_info(instance)
		self.cache(inf)
		self.set_dirty(inf)
		inf._meta["do-cache"] = True
		signals.fire("start-tracking-changes", instance=instance)

	def model_do_not_cache(self, instance):
		inf = get_inst_info(instance)
		self.uncache(inf)
		inf._meta["do-cache"] = False
		signals.fire("stop-tracking-changes", instance=instance)

	def model_history_reset(self, instance, **kwargs):
		raise NotImplementedError

	def model_history_undo(self, instance, fieldname, **kwargs):
		raise NotImplementedError

	def model_history_redo(self, instance, fieldname, **kwargs):
		raise NotImplementedError

	def relation_pre_get(self, manager, **kwargs):
		pass
	
	def relation_post_get(self, manager, **kwargs):
		pass

	def relation_pre_set(self, manager, values, **kwargs):
		pass
	
	def relation_post_set(self, manager, values, **kwargs):
		pass

	def relation_pre_delete(self, manager, **kwargs):
		pass

	def relation_post_delete(self, manager, **kwargs):
		pass

	def relation_pre_add(self, manager, values, **kwargs):
		pass

	def relation_post_add(self, manager, values, **kwargs):
		pass

	def relation_pre_remove(self, manager, values, **kwargs):
		pass

	def relation_post_remove(self, manager, values, **kwargs):
		pass