Drill down support.

From: Jeremy Orlow <jorlow@google.com>
Signed-off-by: Martin Bligh <mbligh@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@1105 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/tko/compose_query.cgi b/tko/compose_query.cgi
index 96f8489..28d66ba 100644
--- a/tko/compose_query.cgi
+++ b/tko/compose_query.cgi
@@ -65,6 +65,21 @@
 	'status': 'status_word',
 }
 
+next_field = {
+	'machine_group': 'hostname',
+	'hostname': 'tag',
+	'tag': 'tag',
+
+	'kernel': 'test',
+	'test': 'label',
+	'label': 'label',
+
+	'reason': 'reason',
+	'user': 'user',
+	'status': 'status',
+}
+
+
 
 def parse_field(form, form_field, field_default):
 	if not form_field in form:
@@ -106,6 +121,25 @@
 	raise "Unknown field"
 
 
+def construct_link(row_val, column_val):
+	next_row = row_field
+	next_column = column_field
+	condition_list = []
+	if condition_field != '':
+		condition_list.append(condition_field)
+	if row_val:
+		next_row = next_field[row_field]
+		condition_list.append('%s%s%s%s' % (row_field, '%3D%27',
+		                                    row_val, '%27'))
+	if column_val:
+		next_column = next_field[column_field]
+		condition_list.append('%s%s%s%s' % (column_field, '%3D%27',
+		                                    column_val, '%27'))
+	next_condition = '%26'.join(condition_list)
+	return 'compose_query.cgi?columns=%s&rows=%s&condition=%s' % (
+	                next_column, next_row, next_condition)
+
+
 def create_select_options(selected_val):
 	ret = ""
 
@@ -142,7 +176,7 @@
 
 	ret = frontend.get_matrix_data(db, field_dict[column_field],
 	                               field_dict[row_field], where)
-	(data, column_list, row_list, stat_list) = ret
+	(data, column_list, row_list, stat_list, job_tags) = ret
 
 	if not row_list:
 		msg = "There are no results for this query (yet?)."
@@ -151,22 +185,32 @@
 	smart_sort(row_list, row_field)
 	smart_sort(column_list, column_field)
 
-	header_row = [display.box("", header=True)]
+	link = 'compose_query.cgi?columns=%s&rows=%s&condition=%s' % (
+	                row_field, column_field, condition_field)
+	header_row = [display.box("<center>(Flip Axis)</center>", link=link)]
+
 	for column in column_list:
-		header_row.append(display.box(column, header=True))
+		link = construct_link(None, column)
+		header_row.append(display.box(column, header=True, link=link))
 
 	matrix = [header_row]
 	for row in row_list:
-		cur_row = [display.box(row)]
+		link = construct_link(row, None)
+		cur_row = [display.box(row, header=True, link=link)]
 		for column in column_list:
 			try:
 				box_data = data[column][row]
 			except:
 				cur_row.append(display.box(None, None))
 				continue
+			job_tag = job_tags[column][row]
+			if job_tag:
+				link = '/results/%s/' % job_tag
+			else:
+				link = construct_link(row, column)
 			cur_row.append(display.status_precounted_box(db,
-			                                        box_data,
-			                                        ""))
+			                                             box_data,
+			                                             link))
 		matrix.append(cur_row)
 
 	return matrix
diff --git a/tko/frontend.py b/tko/frontend.py
index 09f107b..5f431f3 100755
--- a/tko/frontend.py
+++ b/tko/frontend.py
@@ -66,25 +66,32 @@
 	# Return a 3-d hash of data - [x-value][y-value][status_word]
 	# Searches on the test_view table - x_axis and y_axis must both be
 	# column names in that table.
-	assert x_axis != y_axis
-	fields = '%s, %s, status, COUNT(status_word)' % (x_axis, y_axis)
+	fields = ('%s, %s, status, COUNT(status_word), ' +
+	          'LEFT(GROUP_CONCAT(job_tag), 100)' # limit what's returned
+		 ) % (x_axis, y_axis)
 	group_by = '%s, %s, status' % (x_axis, y_axis)
 	rows = db.select(fields, 'test_view', where=where, group_by=group_by)
 
 	data = {}
+	job_tags = {}
 	x_set = set()
 	y_set = set()
 	status_set = set()
-	for (x, y, status, count) in rows:
+	for (x, y, status, count, job_tag) in rows:
 		if not data.has_key(x):
 			data[x] = {}
+			job_tags[x] = {}
 		if not data[x].has_key(y):
 			data[x][y] = {}
 		data[x][y][status] = count
+		if job_tags[x].has_key(y) or count != 1:
+			job_tags[x][y] = None
+		else:
+			job_tags[x][y] = job_tag
 		x_set.add(x)
 		y_set.add(y)
 		status_set.add(status)
-	return (data, list(x_set), list(y_set), list(status_set))
+	return (data, list(x_set), list(y_set), list(status_set), job_tags)
 
 
 class anygroup:
diff --git a/tko/machine_kernel.cgi b/tko/machine_kernel.cgi
index f9ffc7d..dbd52bb 100755
--- a/tko/machine_kernel.cgi
+++ b/tko/machine_kernel.cgi
@@ -29,7 +29,7 @@
 	display.print_main_header()
 
 	ret = frontend.get_matrix_data(db, 'machine_group', 'kernel_printable')
-	(data, group_list, kernel_list, status_list) = ret
+	(data, group_list, kernel_list, status_list, job_tags) = ret
 
 	groups = frontend.group.select(db)
 	group_names = [display.group_name(g) for g in groups]