3 class CommitLogFetcher {
5 function __construct($db) {
9 function fetch_for_tasks($task_id_list, $task_by_id)
11 $commit_rows = $this->db->query_and_fetch_all('SELECT task_commits.*, commits.*, committers.*
12 FROM task_commits, commits LEFT OUTER JOIN committers ON commit_committer = committer_id
13 WHERE taskcommit_commit = commit_id AND taskcommit_task = ANY ($1)', array('{' . implode(', ', $task_id_list) . '}'));
14 if (!is_array($commit_rows))
18 foreach ($commit_rows as &$commit_row) {
19 $associated_task = &$task_by_id[$commit_row['taskcommit_task']];
20 $commit = $this->format_commit($commit_row, $commit_row);
21 $commit['repository'] = $commit_row['commit_repository'];
22 array_push($commits, $commit);
23 array_push($associated_task[Database::is_true($commit_row['taskcommit_is_fix']) ? 'fixes' : 'causes'], $commit_row['commit_id']);
28 function repository_id_from_name($name)
30 $repository_row = $this->db->select_first_row('repositories', 'repository', array('name' => $name));
33 return $repository_row['repository_id'];
36 function fetch_between($repository_id, $first, $second, $keyword = NULL) {
37 $statements = 'SELECT commit_id as "id",
38 commit_revision as "revision",
39 commit_parent as "parent",
40 commit_time as "time",
41 committer_name as "authorName",
42 committer_account as "authorEmail",
43 commit_message as "message"
44 FROM commits LEFT OUTER JOIN committers ON commit_committer = committer_id
45 WHERE commit_repository = $1 AND commit_reported = true';
46 $values = array($repository_id);
48 if ($first && $second) {
49 $first_commit = $this->commit_for_revision($repository_id, $first);
50 $second_commit = $this->commit_for_revision($repository_id, $second);
51 $first = $first_commit['commit_time'];
52 $second = $second_commit['commit_time'];
53 $column_name = 'commit_time';
54 if (!$first || !$second) {
55 $first = $first_commit['commit_order'];
56 $second = $second_commit['commit_order'];
57 $column_name = 'commit_order';
60 $in_order = $first < $second;
61 array_push($values, $in_order ? $first : $second);
62 $statements .= ' AND ' . $column_name . ' >= $' . count($values);
63 array_push($values, $in_order ? $second : $first);
64 $statements .= ' AND ' . $column_name . ' <= $' . count($values);
68 array_push($values, '%' . Database::escape_for_like($keyword) . '%');
69 $keyword_index = '$' . count($values);
70 array_push($values, ltrim($keyword, 'r'));
71 $revision_index = '$' . count($values);
73 AND ((committer_name LIKE $keyword_index OR committer_account LIKE $keyword_index) OR commit_revision = $revision_index)";
76 $commits = $this->db->query_and_fetch_all($statements . ' ORDER BY commit_time, commit_order', $values);
77 if (!is_array($commits))
80 foreach ($commits as &$commit)
81 $commit['time'] = Database::to_js_time($commit['time']);
86 function fetch_oldest($repository_id) {
87 return $this->format_single_commit($this->db->select_first_row('commits', 'commit', array('repository' => $repository_id), 'time'));
90 function fetch_latest($repository_id) {
91 return $this->format_single_commit($this->db->select_last_row('commits', 'commit', array('repository' => $repository_id), 'time'));
94 function fetch_last_reported($repository_id) {
95 return $this->format_single_commit($this->db->select_last_row('commits', 'commit', array('repository' => $repository_id, 'reported' => true), 'time'));
98 function fetch_revision($repository_id, $revision) {
99 return $this->format_single_commit($this->commit_for_revision($repository_id, $revision));
102 private function commit_for_revision($repository_id, $revision) {
103 $all_but_first = substr($revision, 1);
104 if ($revision[0] == 'r' && ctype_digit($all_but_first))
105 $revision = $all_but_first;
106 $commit_info = array('repository' => $repository_id, 'revision' => $revision);
107 $row = $this->db->select_last_row('commits', 'commit', $commit_info);
109 exit_with_error('UnknownCommit', $commit_info);
113 private function format_single_commit($commit_row) {
116 $committer = $this->db->select_first_row('committers', 'committer', array('id' => $commit_row['commit_committer']));
117 return array($this->format_commit($commit_row, $committer));
120 private function format_commit($commit_row, $committer_row) {
122 'id' => $commit_row['commit_id'],
123 'revision' => $commit_row['commit_revision'],
124 'parent' => $commit_row['commit_parent'],
125 'time' => Database::to_js_time($commit_row['commit_time']),
126 'order' => $commit_row['commit_order'],
127 'authorName' => $committer_row ? $committer_row['committer_name'] : null,
128 'authorEmail' => $committer_row ? $committer_row['committer_account'] : null,
129 'message' => $commit_row['commit_message']