Add API to upload a patched build for a custom A/B testing
[WebKit.git] / Websites / perf.webkit.org / public / include / build-requests-fetcher.php
1 <?php
2
3 require_once('test-path-resolver.php');
4 require_once('uploaded-file-helpers.php');
5
6 class BuildRequestsFetcher {
7     function __construct($db) {
8         $this->db = $db;
9         $this->rows = null;
10         $this->commit_sets = array();
11         $this->commits_by_id = array();
12         $this->commits = array();
13         $this->commit_sets_by_id = array();
14         $this->uploaded_files = array();
15         $this->uploaded_files_by_id = array();
16     }
17
18     function fetch_for_task($task_id) {
19         $this->rows = $this->db->query_and_fetch_all('SELECT *, testgroup_task as task_id
20             FROM build_requests LEFT OUTER JOIN builds ON request_build = build_id, analysis_test_groups
21             WHERE request_group = testgroup_id AND testgroup_task = $1
22             ORDER BY request_group, request_order', array($task_id));
23     }
24
25     function fetch_for_group($task_id, $test_group_id) {
26         $this->rows = $this->db->query_and_fetch_all('SELECT *
27             FROM build_requests LEFT OUTER JOIN builds ON request_build = build_id
28             WHERE request_group = $1 ORDER BY request_order', array($test_group_id));
29         foreach ($this->rows as &$row)
30             $row['task_id'] = $task_id;
31     }
32
33     function fetch_incomplete_requests_for_triggerable($triggerable_id) {
34         $this->rows = $this->db->query_and_fetch_all('SELECT *, test_groups.testgroup_task as task_id FROM build_requests,
35             (SELECT testgroup_id, testgroup_task, (case when testgroup_author is not null then 0 else 1 end) as author_order, testgroup_created_at
36                 FROM analysis_test_groups WHERE EXISTS
37                     (SELECT 1 FROM build_requests WHERE testgroup_id = request_group AND request_status
38                         IN (\'pending\', \'scheduled\', \'running\'))) AS test_groups
39             WHERE request_triggerable = $1 AND request_group = test_groups.testgroup_id
40             ORDER BY author_order, testgroup_created_at, request_order', array($triggerable_id));
41     }
42
43     function fetch_request($request_id) {
44         $this->rows = $this->db->select_rows('build_requests', 'request', array('id' => $request_id));
45     }
46
47     function has_results() { return is_array($this->rows); }
48     function results() { return $this->results_internal(false); }
49     function results_with_resolved_ids() { return $this->results_internal(true); }
50
51     private function results_internal($resolve_ids) {
52         if (!$this->rows)
53             return array();
54
55         $id_to_platform_name = array();
56         if ($resolve_ids) {
57             foreach ($this->db->select_rows('platforms', 'platform', array()) as $platform)
58                 $id_to_platform_name[$platform['platform_id']] = $platform['platform_name'];
59         }
60         $test_path_resolver = new TestPathResolver($this->db);
61
62         $requests = array();
63         foreach ($this->rows as $row) {
64             $test_id = $row['request_test'];
65             $platform_id = $row['request_platform'];
66             $commit_set_id = $row['request_commit_set'];
67
68             $this->fetch_commits_for_set_if_needed($commit_set_id, $resolve_ids);
69
70             array_push($requests, array(
71                 'id' => $row['request_id'],
72                 'task' => $row['task_id'],
73                 'triggerable' => $row['request_triggerable'],
74                 'repositoryGroup' => $row['request_repository_group'],
75                 'test' => $resolve_ids ? $test_path_resolver->path_for_test($test_id) : $test_id,
76                 'platform' => $resolve_ids ? $id_to_platform_name[$platform_id] : $platform_id,
77                 'testGroup' => $row['request_group'],
78                 'order' => $row['request_order'],
79                 'commitSet' => $commit_set_id,
80                 'status' => $row['request_status'],
81                 'url' => $row['request_url'],
82                 'build' => $row['request_build'],
83                 'createdAt' => $row['request_created_at'] ? strtotime($row['request_created_at']) * 1000 : NULL,
84             ));
85         }
86         return $requests;
87     }
88
89     function commit_sets() { return $this->commit_sets; }
90     function commits() { return $this->commits; }
91     function uploaded_files() { return $this->uploaded_files; }
92
93     private function fetch_commits_for_set_if_needed($commit_set_id, $resolve_ids) {
94         if (array_key_exists($commit_set_id, $this->commit_sets_by_id))
95             return;
96
97         $commit_set_items = $this->db->query_and_fetch_all('SELECT *
98             FROM commit_set_items LEFT OUTER JOIN  commits ON commitset_commit = commit_id
99                 LEFT OUTER JOIN repositories ON repository_id = commit_repository
100                 WHERE commitset_set = $1', array($commit_set_id));
101
102         $custom_roots = array();
103         $revision_items = array();
104         foreach ($commit_set_items as $row) {
105             $repository_id = $resolve_ids ? $row['repository_name'] : $row['repository_id'];
106             $revision = $row['commit_revision'];
107             $commit_time = $row['commit_time'];
108
109             $root_file_id = $row['commitset_root_file'];
110             $commit_id = $row['commitset_commit'];
111             if ($root_file_id && !$commit_id) {
112                 $this->add_uploaded_file($root_file_id);
113                 array_push($custom_roots, $root_file_id);
114                 continue;
115             }
116
117             $patch_file_id = $row['commitset_patch_file'];
118             if ($patch_file_id)
119                 $this->add_uploaded_file($patch_file_id);
120
121             $root_file_id = $row['commitset_root_file'];
122             if ($root_file_id)
123                 $this->add_uploaded_file($root_file_id);
124
125             array_push($revision_items, array('commit' => $row['commit_id'], 'patch' => $patch_file_id, 'rootFile' => $root_file_id));
126
127             if (array_key_exists($commit_id, $this->commits_by_id))
128                 continue;
129
130             array_push($this->commits, array(
131                 'id' => $commit_id,
132                 'repository' => $repository_id,
133                 'revision' => $revision,
134                 'time' => Database::to_js_time($commit_time)));
135
136             $this->commits_by_id[$commit_id] = TRUE;
137         }
138
139         $this->commit_sets_by_id[$commit_set_id] = TRUE;
140
141         array_push($this->commit_sets, array('id' => $commit_set_id, 'revisionItems' => $revision_items, 'customRoots' => $custom_roots));
142     }
143
144     private function add_uploaded_file($root_file_id)
145     {
146         if (!array_key_exists($root_file_id, $this->uploaded_files_by_id)) {
147             $uploaded_file_row = $this->db->select_first_row('uploaded_files', 'file', array('id' => $root_file_id));
148             array_push($this->uploaded_files, format_uploaded_file($uploaded_file_row));
149         }
150     }
151 }
152
153 ?>