1package autotest.tko;
2
3import autotest.common.Utils;
4import autotest.common.ui.MultiListSelectPresenter.Item;
5
6import com.google.gwt.json.client.JSONObject;
7
8/**
9 * A field associated with test results.  The user may
10 * * view this field in table view,
11 * * sort by this field in table view,
12 * * group by this field in spreadsheet or table view, and
13 * * filter on this field in the SQL condition.
14 * It's assumed that the name returned by getSqlName() is a field returned by the server which may
15 * also be used for grouping and sorting.  Filtering, however, is done separately (through
16 * getSqlCondition()), so HeaderFields may generate arbitrary SQL to perform filtering.
17 * HeaderFields may also add arbitrary query arguments to support themselves.
18 *
19 * While the set of HeaderFields active in the application may change at runtime, HeaderField
20 * objects themselves are immutable.
21 */
22public abstract class HeaderField implements Comparable<HeaderField> {
23    protected String name;
24    protected String sqlName;
25
26    /**
27     * @param name Display name for this field (i.e. "Job name")
28     * @param sqlName SQL field name (i.e. "job_name")
29     */
30    protected HeaderField(String name, String sqlName) {
31        this.name = name;
32        this.sqlName = sqlName;
33    }
34
35    public int compareTo(HeaderField other) {
36        return name.compareTo(other.name);
37    }
38
39    /**
40     * A common helper for SQL conditions.
41     */
42    protected String getSimpleSqlCondition(String field, String value) {
43        if (value.equals(Utils.JSON_NULL)) {
44          return field + " is null";
45        } else {
46          return field + " = '" + TkoUtils.escapeSqlValue(value) + "'";
47        }
48    }
49
50    /**
51     * Get the SQL WHERE clause to filter on the given value for this header.
52     */
53    public abstract String getSqlCondition(String value);
54
55    /**
56     * Get the name of this field.
57     */
58    public String getName() {
59        return name;
60    }
61
62    /**
63     * Get the name to use for this field in a SQL select.
64     */
65    public String getSqlName() {
66        return sqlName;
67    }
68
69    /**
70     * Get a quoted version of getSqlName() safe for use directly in SQL.
71     */
72    public String getQuotedSqlName() {
73        String sqlName = getSqlName();
74        if (sqlName.matches(".+\\(.+\\)")) {
75            // don't quote fields involving SQL functions
76            return sqlName;
77        }
78        return "`" + sqlName + "`";
79    }
80
81    @Override
82    public String toString() {
83        return "HeaderField<" + getName() + ", " + getSqlName() + ">";
84    }
85
86    /**
87     * Should this field be provided as a choice for the user to select?
88     */
89    public boolean isUserSelectable() {
90        return true;
91    }
92
93    /**
94     * @return a MultiListSelectPresenter.Item for this HeaderField.
95     */
96    public Item getItem() {
97        return Item.createItem(getName(), getSqlName());
98    }
99
100    /**
101     * Add necessary parameters to an RPC request to select this field.  Does nothing by default.
102     * @param parameters query parameters
103     */
104    public void addQueryParameters(JSONObject parameters) {}
105}
106