summaryrefslogtreecommitdiff
path: root/tko/compose_query.cgi
blob: b8ec758f17429c1f05406779f91bca98f5f18201 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/python

"""
Selects all rows and columns that satisfy the condition specified
and draws the matrix. There is a seperate SQL query made for every (x,y)
in the matrix.
"""


print "Content-type: text/html\n"
import cgi, cgitb, re
import sys, os

tko = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
sys.path.insert(0, tko)

import display, frontend, db

cgitb.enable()
db = db.db()

def generate_sql_condition(condition_list):
	""" generate the sql for the condition list."""
	sql = ""
	value = []
	for field, operator, values in condition_list:
		if len(values) == 1:
			sql += " and %s%s%%s" % (field, operator)
			value.append(values[0][0])
		elif len(values) > 1:
			sql += " and "
			expression = [" %s %s %%s" % (field, operator) for val in values]
			for val in values:
				value.append(val[0])
			sql += "(%s)" % " or ".join(expression)
	return sql, value


def prune_list(thelist, condition_sql, condition_value):
	""" keep track of which columns do not have any elements."""
	pruned_list = []
	for g in thelist:
		sql = "t where %s=%%s " % g.idx_name
		value = [g.idx_value]
		sql += condition_sql
		value.extend(condition_value)
		tests = frontend.test.select_sql(db, sql, value)
		if len(tests) > 0:
			pruned_list.append(g)
	return pruned_list


def ParseCondition(condition):
	""" parse the condition into independent clauses."""
	condition_list = []
	if not condition:
		return condition_list
	attribute_re = r"(\w+)"
	op_re = r"(=|!=)"
	value_re = r"('[^']*')"
	# condition is clause & clause & ..
	clause_re = r"%s\s*%s\s*%s" % (attribute_re, op_re, value_re)
	condition_re = re.compile(r"^\s*%s(\s*&\s*%s)*\s*$" % (clause_re, clause_re))
	if not condition_re.match(condition):
		print "Condition not in the correct format: %s" % condition
		sys.exit(0)
	triples = []
	for clause in [c.strip() for c in condition.split('&')]:
		attribute, op, value = re.match(clause_re, clause).groups()
		triples.append((attribute, op, value))
	for (field_name, operator, value) in triples:
		match, field = frontend.select(db, field_name, value)
		if len(match) > 0:
			condition_list.append((field, operator, match))
		else:
			print "No matching records found for condition %s." % \
			      condition
			sys.exit(0)
	return condition_list


def main():

	# parse the fields from the form.
	form = cgi.FieldStorage()
	columns = 'kernel'
	rows = 'test'
	condition = None
	for field in form:
		value = form[field].value
		if field == 'columns':
			columns = value
		elif field == 'rows':
			rows = value
		elif field == 'condition':
			condition = value

	# parse the conditions into sql query and value list.
	condition_sql = ""
	condition_value = []
	if condition:
		condition_list = ParseCondition(condition)
		condition_sql, condition_value = generate_sql_condition(condition_list)

	# get all possible column values.
	column_groups = frontend.anygroup.selectunique(db, columns)

	# get all possible row values.
	row_groups = frontend.anygroup.selectunique(db,rows)
	# keep only those values in rows/columns that have a test
	# corresponding to it.
	row_groups = prune_list(row_groups, condition_sql, condition_value)
	column_groups = prune_list(column_groups, condition_sql, condition_value)

	# prepare the header for the table.
	headers = [g.name for g in column_groups]

	header_row = [display.box(x, header=True) for x in headers]
	header_row.insert(0, display.box("", header=True))

	matrix = [header_row]

	for r_group in row_groups:
		row = [display.box(r_group.name)]
		# get individual unit values
		for c_group in column_groups:
			sql = "t where %s=%%s and %s=%%s" % (r_group.idx_name,
							     c_group.idx_name)
			value = [r_group.idx_value, c_group.idx_value]
			sql += condition_sql
			value.extend(condition_value)
			tests = frontend.test.select_sql(db, sql, value)
			value_str = [str(val) for val in value]
			link = 'test.cgi?sql=%s&values=%s' % \
				(sql, ','.join(value_str))
			row.append(display.status_count_box(db, tests, link))
		matrix.append(row)
	display.print_table(matrix)


main()