← Back to team overview

zeitgeist team mailing list archive

[Merge] lp:~zeitgeist/zeitgeist/db4fixes into lp:zeitgeist

 

Siegfried Gevatter has proposed merging lp:~zeitgeist/zeitgeist/db4fixes into lp:zeitgeist.

Requested reviews:
  Zeitgeist Framework Team (zeitgeist)

For more details, see:
https://code.launchpad.net/~zeitgeist/zeitgeist/db4fixes/+merge/59115
-- 
https://code.launchpad.net/~zeitgeist/zeitgeist/db4fixes/+merge/59115
Your team Zeitgeist Framework Team is requested to review the proposed merge of lp:~zeitgeist/zeitgeist/db4fixes into lp:zeitgeist.
=== modified file '_zeitgeist/engine/main.py'
--- _zeitgeist/engine/main.py	2011-04-15 17:13:49 +0000
+++ _zeitgeist/engine/main.py	2011-04-26 18:52:27 +0000
@@ -163,6 +163,7 @@
 				log.error("Event %i broken: Table %s has no id %i" \
 						%(row["id"], field, row[field]))
 				return None
+		event.origin = row["event_origin_uri"] or ""
 		event.payload = row["payload"] or "" # default payload: empty string
 		return event
 	
@@ -338,6 +339,10 @@
 				if value:
 					subwhere.add_text_condition("actor", value, wildcard, negation, cache=self._actor)
 				
+				value, negation, wildcard = parse_operators(Event, Event.Origin, event_template.origin)
+				if value:
+					subwhere.add_text_condition("origin", value, wildcard, negation)
+				
 				if subject_templates is not None:
 					for subject_template in subject_templates:
 						value, negation, wildcard = parse_operators(Subject, Subject.Interpretation, subject_template.interpretation)
@@ -372,7 +377,12 @@
 							value = getattr(subject_template, key)
 							if value:
 								value, negation, wildcard = parse_operators(Subject, getattr(Subject, key.title()), value)
-								subwhere.add_text_condition("subj_%s" %key, value, wildcard, negation)
+								subwhere.add_text_condition("subj_%s" % key, value, wildcard, negation)
+						
+						if subject_template.current_uri:
+							value, negation, wildcard = parse_operators(Subject,
+								Subject.CurrentUri, subject_template.current_uri)
+							subwhere.add_text_condition("subj_current_uri", value, wildcard, negation)
 						
 						if subject_template.storage:
 							subwhere.add_text_condition("subj_storage", subject_template.storage)
@@ -446,7 +456,8 @@
 		elif where:
 			sql += " WHERE " + where.sql
 		
-		sql += (" ORDER BY timestamp DESC",
+		sql += (
+			" ORDER BY timestamp DESC",
 			" ORDER BY timestamp ASC",
 			# thekorn: please note, event.subj_id == uri.id, as in
 			# the subj_id points directly to an entry in the uri table,
@@ -587,11 +598,13 @@
 			event.timestamp = get_timestamp_for_now()
 		if not event.interpretation == Interpretation.MOVE_EVENT:
 			for subject in event.subjects:
-				if not subject.uri == subject.current_uri:
+				if not subject.current_uri:
+					subject.current_uri = subject.uri
+				elif not subject.uri == subject.current_uri:
 					raise ValueError("Illegal event: unless event.interpretation is 'MOVE_EVENT' then subject.uri and subject.current_uri have to be the same")
 		if event.interpretation == Interpretation.MOVE_EVENT:
 			for subject in event.subjects:
-				if subject.uri == subject.current_uri:
+				if subject.uri == subject.current_uri or not subject.current_uri:
 					raise ValueError("Redundant event: event.interpretation indicates the uri has been moved yet the subject.uri and subject.current_uri are identical")
 			
 		id = self.next_event_id()
@@ -609,9 +622,9 @@
 		_current_uri = [subject.current_uri
 			for subject in event.subjects if subject.current_uri]
 		self._cursor.execute("INSERT OR IGNORE INTO uri (value) %s"
-			% " UNION ".join(["SELECT ?"] * (len(event.subjects) +
-				len(_origin) + len(_current_uri))),
-			[subject.uri for subject in event.subjects] + _origin + _current_uri)
+			% " UNION ".join(["SELECT ?"] * (1 + len(event.subjects) +
+				len(_origin) + len(_current_uri))), [event.origin] + _origin +
+			[subject.uri for subject in event.subjects] + _current_uri)
 		
 		# Make sure all mimetypes are inserted
 		_mimetype = [subject.mimetype for subject in event.subjects \
@@ -633,7 +646,7 @@
 				% " UNION ".join(["SELECT ?"] * len(_storage)), _storage)
 		
 		try:
-			for subject in event.subjects:	
+			for subject in event.subjects:
 				self._cursor.execute("""
 					INSERT INTO event (
 						id, timestamp, interpretation, manifestation, actor,
@@ -641,7 +654,9 @@
 						subj_interpretation, subj_manifestation, subj_origin,
 						subj_mimetype, subj_text, subj_storage
 					) VALUES (
-						?, ?, ?, ?, ?, ?, ?,
+						?, ?, ?, ?, ?,
+						(SELECT id FROM uri WHERE value=?),
+						?,
 						(SELECT id FROM uri WHERE value=?),
 						(SELECT id FROM uri WHERE value=?),
 						?, ?,
@@ -655,7 +670,7 @@
 						self._interpretation[event.interpretation],
 						self._manifestation[event.manifestation],
 						self._actor[event.actor],
-						None, # event origin
+						event.origin,
 						payload_id,
 						subject.uri,
 						subject.current_uri,

=== modified file '_zeitgeist/engine/sql.py'
--- _zeitgeist/engine/sql.py	2011-04-07 08:38:00 +0000
+++ _zeitgeist/engine/sql.py	2011-04-26 18:52:27 +0000
@@ -30,6 +30,7 @@
 log = logging.getLogger("zeitgeist.sql")
 
 TABLE_MAP = {
+	"origin": "uri",
 	"subj_mimetype": "mimetype",
 	"subj_origin": "uri",
 	"subj_uri": "uri",
@@ -580,17 +581,22 @@
 			
 	def add_text_condition(self, column, value, like=False, negation=False, cache=None):
 		if like:
-			assert column in ("subj_uri", "subj_origin", "actor", "subj_mimetype"), \
-				"prefix search on the %r column is not supported by zeitgeist" %column
+			assert column in ("origin", "subj_uri", "subj_current_uri",
+			"subj_origin", "actor", "subj_mimetype"), \
+				"prefix search on the %r column is not supported by zeitgeist" % column
 			if column == "subj_uri":
 				# subj_id directly points to the id of an uri entry
 				view_column = "subj_id"
+			elif column == "subj_current_uri":
+				view_column = "subj_id_current"
 			else:
 				view_column = column
 			optimized_glob, value = self.optimize_glob("id", TABLE_MAP.get(column, column), value)
 			sql = "%s %sIN (%s)" %(view_column, self.NOT if negation else "", optimized_glob)
 		else:
-			if column == "subj_origin":
+			if column == "origin":
+				column ="event_origin_uri"
+			elif column == "subj_origin":
 				column = "subj_origin_uri"
 			sql = "%s %s= ?" %(column, "!" if negation else "")
 			if cache is not None:

=== modified file 'test/data/twenty_events.js'
--- test/data/twenty_events.js	2010-10-10 13:15:54 +0000
+++ test/data/twenty_events.js	2011-04-26 18:52:27 +0000
@@ -4,6 +4,7 @@
 		"interpretation" : "stfu:OpenEvent",
 		"manifestation" : "stfu:UserActivity",
 		"actor" : "firefox",
+		"origin" : "origin2",
 		"subjects" : [
 			{
 				"uri" : "file:///tmp/foo.txt",
@@ -20,6 +21,7 @@
 		"interpretation" : "stfu:OpenEvent",
 		"manifestation" : "stfu:UserActivity",
 		"actor" : "icedove",
+		"origin" : "origin1",
 		"subjects" : [
 			{
 				"uri" : "file:///tmp/foo.txt",
@@ -36,6 +38,7 @@
 		"interpretation" : "stfu:OpenEvent",
 		"manifestation" : "stfu:UserActivity",
 		"actor" : "firefox",
+		"origin" : "origin1",
 		"subjects" : [
 			{
 				"uri" : "file:///tmp/foo.txt",
@@ -52,6 +55,7 @@
 		"interpretation" : "stfu:OpenEvent",
 		"manifestation" : "stfu:UserActivity",
 		"actor" : "icedove",
+		"origin" : "origin3",
 		"subjects" : [
 			{
 				"uri" : "file:///tmp/foo.txt",

=== modified file 'test/datamodel-test.py'
--- test/datamodel-test.py	2011-04-07 06:44:17 +0000
+++ test/datamodel-test.py	2011-04-26 18:52:27 +0000
@@ -344,8 +344,8 @@
 	def testCurrentUri(self):
 		subj = Subject()
 		subj.uri = "Wonneproppen"
-		self.assertTrue(subj.uri, "Wonneproppen")
-		self.assertTrue(subj.current_uri, "Wonneproppen")
+		self.assertEqual(subj.uri, "Wonneproppen")
+		self.assertEqual(subj.current_uri, "")
 
 
 class TimeRangeTest (unittest.TestCase):
@@ -400,7 +400,7 @@
 		self.assertTrue(subject.uri == subject.current_uri == "")
 		uri = "file:///path/to/file"
 		subject.uri = uri
-		self.assertEqual(subject.uri, subject.current_uri)
+		self.assertEqual(subject.current_uri, "")
 		new_uri = "http:///www.remote.location";
 		subject.current_uri = new_uri
 		self.assertEqual(subject.current_uri, new_uri)

=== modified file 'test/engine-test.py'
--- test/engine-test.py	2011-04-22 19:42:38 +0000
+++ test/engine-test.py	2011-04-26 18:52:27 +0000
@@ -390,6 +390,26 @@
 		for event in events:
 			self.assertEqual(event.manifestation, "stfu:EpicFailActivity")
 	
+	def testFindWithEventOrigin(self):
+		import_events("test/data/twenty_events.js", self.engine)
+		event_template = Event.new_for_values(origin="origin3")
+		result = self.engine.find_eventids(TimeRange.always(),
+			[event_template], StorageState.Any, 0, 1)
+		events = self.engine.get_events(result)
+		
+		self.assertTrue(len(events) > 0)
+		self.assertTrue(all(ev.origin == "origin3" for ev in events))
+	
+	def testFindWithEventOriginNegatedWildcard(self):
+		import_events("test/data/twenty_events.js", self.engine)
+		event_template = Event.new_for_values(origin="!origin*")
+		result = self.engine.find_eventids(TimeRange.always(),
+			[event_template], StorageState.Any, 0, 1)
+		events = self.engine.get_events(result)
+		
+		self.assertTrue(len(events) > 0)
+		self.assertFalse(any(ev.origin.startswith("origin") for ev in events))
+	
 	def testFindWithSubjectOrigin(self):
 		import_events("test/data/five_events.js", self.engine)
 		subj = Subject.new_for_values(origin="file:///tmp")
@@ -767,7 +787,14 @@
 		template = Event.new_for_values(
 			subject_uri = "http://*";
 		)
-		
+		ids = self.engine.find_eventids(TimeRange.always(),
+			[template,], StorageState.Any, 10, ResultType.MostRecentEvents
+		)
+		self.assertEquals(1, len(ids))
+
+		template = Event.new_for_values(
+			subject_current_uri = "http://*";
+		)
 		ids = self.engine.find_eventids(TimeRange.always(),
 			[template,], StorageState.Any, 10, ResultType.MostRecentEvents
 		)
@@ -776,7 +803,6 @@
 		template = Event.new_for_values(
 			subject_origin = "file://*"
 		)
-		
 		ids = self.engine.find_eventids(TimeRange.always(),
 			[template,], StorageState.Any, 10, ResultType.MostRecentEvents
 		)
@@ -1095,8 +1121,6 @@
 			[], StorageState.Any, 0, ResultType.LeastRecentActor)
 		self.assertEquals([e.timestamp for e in events], ['3', '4'])
 
-
-
 	def testResultTypesMostPopularSubjectOrigin(self):
 		import_events("test/data/twenty_events.js", self.engine)
 		

=== modified file 'test/testutils.py'
--- test/testutils.py	2011-01-17 15:54:47 +0000
+++ test/testutils.py	2011-04-26 18:52:27 +0000
@@ -51,6 +51,7 @@
 	ev.interpretation = str(d.get("interpretation", "").encode("UTF-8"))
 	ev.manifestation = str(d.get("manifestation", "").encode("UTF-8"))
 	ev.actor = str(d.get("actor", "").encode("UTF-8"))
+	ev.origin = str(d.get("origin", "").encode("UTF-8"))
 	ev.payload = str(d.get("payload", "").encode("UTF-8"))
 	
 	subjects = d.get("subjects", [])

=== modified file 'zeitgeist/datamodel.py'
--- zeitgeist/datamodel.py	2011-04-07 06:44:17 +0000
+++ zeitgeist/datamodel.py	2011-04-26 18:52:27 +0000
@@ -470,6 +470,15 @@
 			self.__class__.__name__, super(Subject, self).__repr__()
 		)
 	
+	def __eq__(self, other):
+		for field in Subject.Fields:
+			if field is Subject.CurrentUri and not self[field] or \
+			not other[field]:
+				continue
+			if self[field] != other[field]:
+				return False
+		return True
+	
 	@staticmethod
 	def new_for_values (**values):
 		"""
@@ -490,11 +499,7 @@
 			if not key in ("uri", "current_uri", "interpretation", "manifestation", "origin",
 						"mimetype", "text", "storage"):
 				raise ValueError("Subject parameter '%s' is not supported" %key)
-			if not key == "current_uri":
-				setattr(self, key, value)
-		# Make sure Uri is set first before Current_Uri to avoid overwriting
-		if "current_uri" in values.keys():
-			setattr(self, "current_uri", values["current_uri"])
+			setattr(self, key, value)
 		return self
 		
 	def get_uri(self):
@@ -502,13 +507,10 @@
 		
 	def set_uri(self, value):
 		self[Subject.Uri] = value
-		self[Subject.CurrentUri] = value
 	uri = property(get_uri, set_uri,
-	doc="Read/write property with the URI of the subject encoded as a string (Warning: writing this property overwrites Current URI")
+	doc="Read/write property with the URI of the subject encoded as a string")
 	
 	def get_current_uri(self):
-		if not self[Subject.CurrentUri] or not self[Subject.CurrentUri].strip():
-			return self[Subject.Uri]
 		return self[Subject.CurrentUri]
 	
 	def set_current_uri(self, value):
@@ -624,9 +626,9 @@
 		Manifestation,
 		Actor,
 		Origin) = range(6)
-		
+	
 	SUPPORTS_NEGATION = (Interpretation, Manifestation, Actor, Origin)
-	SUPPORTS_WILDCARDS = (Actor,)
+	SUPPORTS_WILDCARDS = (Actor, Origin)
 	
 	def __init__(self, struct = None):
 		"""
@@ -719,19 +721,19 @@
 		counterparts in :meth:`Subject.new_for_values`:
 		
 		:param subject_uri:
+		:param subject_current_uri:
 		:param subject_interpretation:
 		:param subject_manifestation:
 		:param subject_origin:
 		:param subject_mimetype:
 		:param subject_text:
 		:param subject_storage:
-		 
-		
 		"""
 		self = cls()
 		for key in values:
 			if not key in ("timestamp", "interpretation", "manifestation",
-				"actor", "origin", "subjects", "subject_uri", "subject_interpretation",
+				"actor", "origin", "subjects", "subject_uri",
+				"subject_current_uri", "subject_interpretation",
 				"subject_manifestation", "subject_origin", "subject_mimetype",
 				"subject_text", "subject_storage"):
 				raise ValueError("Event parameter '%s' is not supported" % key)
@@ -761,13 +763,14 @@
 	
 	@staticmethod
 	def _dict_contains_subject_keys (dikt):
-		if "subject_uri" in dikt : return True
-		elif "subject_interpretation" in dikt : return True
-		elif "subject_manifestation" in dikt : return True
-		elif "subject_origin" in dikt : return True
-		elif "subject_mimetype" in dikt : return True
-		elif "subject_text" in dikt : return True
-		elif "subject_storage" in dikt : return True
+		if "subject_uri" in dikt: return True
+		elif "subject_current_uri" in dikt: return True
+		elif "subject_interpretation" in dikt: return True
+		elif "subject_manifestation" in dikt: return True
+		elif "subject_origin" in dikt: return True
+		elif "subject_mimetype" in dikt: return True
+		elif "subject_text" in dikt: return True
+		elif "subject_storage" in dikt: return True
 		return False
 	
 	def __repr__(self):
@@ -1066,11 +1069,11 @@
 		"ordered ascendingly by the popularity of the actor"))
 	MostRecentActor = enum_factory(("The Actor that has been used to most recently"))
 	LeastRecentActor = enum_factory(("The Actor that has been used to least recently"))	
-	MostRecentOrigin = enum_factory(("The last event of each different origin"))
-	LeastRecentOrigin = enum_factory(("The first event of each different origin"))
-	MostPopularOrigin = enum_factory(("The last event of each different origin,"
+	MostRecentOrigin = enum_factory(("The last event of each different subject origin"))
+	LeastRecentOrigin = enum_factory(("The first event of each different subject origin"))
+	MostPopularOrigin = enum_factory(("The last event of each different subject origin,"
 		"ordered by the popularity of the origins"))
-	LeastPopularOrigin = enum_factory(("The last event of each different origin,"
+	LeastPopularOrigin = enum_factory(("The last event of each different subject origin,"
 		"ordered ascendingly by the popularity of the origin"))
 	OldestActor = enum_factory(("The first event of each different actor"))
 	MostRecentSubjectInterpretation = enum_factory(("One event for each subject interpretation only, "
@@ -1090,7 +1093,6 @@
 	LeastPopularMimeType = enum_factory(("One event for each mimetype only, "
 		"ordered ascendingly by popularity of the mimetype"))
 
-
 INTERPRETATION_DOC = \
 """In general terms the *interpretation* of an event or subject is an abstract
 description of *"what happened"* or *"what is this"*.


Follow ups