3 require_once('../include/json-header.php');
5 function main($paths) {
6 if (count($paths) < 1 || count($paths) > 2)
7 exit_with_error('InvalidRequest');
11 exit_with_error('DatabaseConnectionFailure');
13 if (!is_numeric($paths[0])) {
14 $repository_name = $paths[0];
15 $repository_row = $db->select_first_row('repositories', 'repository', array('name' => $repository_name));
17 exit_with_error('RepositoryNotFound', array('repositoryName' => $repository_name));
18 $repository_id = $repository_row['repository_id'];
20 $repository_id = intval($paths[0]);
22 $filter = array_get($paths, 1);
23 $single_commit = NULL;
26 $keyword = array_get($_GET, 'keyword');
27 $from = array_get($_GET, 'from');
28 $to = array_get($_GET, 'to');
29 $commits = fetch_commits_between($db, $repository_id, $from, $to, $keyword);
30 } else if ($filter == 'oldest') {
31 $single_commit = $db->select_first_row('commits', 'commit', array('repository' => $repository_id), 'time');
32 } else if ($filter == 'latest') {
33 $single_commit = $db->select_last_row('commits', 'commit', array('repository' => $repository_id), 'time');
34 } else if ($filter == 'last-reported') {
35 $single_commit = $db->select_last_row('commits', 'commit', array('repository' => $repository_id, 'reported' => true), 'time');
36 } else if (ctype_alnum($filter)) {
37 $single_commit = commit_from_revision($db, $repository_id, $filter);
40 if (!preg_match('/([A-Za-z0-9]+)[\:\-]([A-Za-z0-9]+)/', $filter, $matches))
41 exit_with_error('UnknownFilter', array('repositoryName' => $repository_name, 'filter' => $filter));
43 $commits = fetch_commits_between($db, $repository_id, $matches[1], $matches[2]);
47 $committer = $db->select_first_row('committers', 'committer', array('id' => $single_commit['commit_committer']));
48 exit_with_success(array('commits' => array(format_commit($single_commit, $committer))));
51 exit_with_success(array('commits' => $commits));
54 function commit_from_revision($db, $repository_id, $revision) {
55 $all_but_first = substr($revision, 1);
56 if ($revision[0] == 'r' && ctype_digit($all_but_first))
57 $revision = $all_but_first;
58 $commit_info = array('repository' => $repository_id, 'revision' => $revision);
59 $row = $db->select_last_row('commits', 'commit', $commit_info);
61 exit_with_error('UnknownCommit', $commit_info);
65 function fetch_commits_between($db, $repository_id, $first, $second, $keyword = NULL) {
66 $statements = 'SELECT commit_id as "id",
67 commit_revision as "revision",
68 commit_parent as "parent",
69 commit_time as "time",
70 committer_name as "authorName",
71 committer_account as "authorEmail",
72 commit_message as "message"
73 FROM commits LEFT OUTER JOIN committers ON commit_committer = committer_id
74 WHERE commit_repository = $1 AND commit_reported = true';
75 $values = array($repository_id);
77 if ($first && $second) {
78 $first_commit = commit_from_revision($db, $repository_id, $first);
79 $second_commit = commit_from_revision($db, $repository_id, $second);
80 $first = $first_commit['commit_time'];
81 $second = $second_commit['commit_time'];
82 $column_name = 'commit_time';
83 if (!$first || !$second) {
84 $first = $first_commit['commit_order'];
85 $second = $second_commit['commit_order'];
86 $column_name = 'commit_order';
89 $in_order = $first < $second;
90 array_push($values, $in_order ? $first : $second);
91 $statements .= ' AND ' . $column_name . ' >= $' . count($values);
92 array_push($values, $in_order ? $second : $first);
93 $statements .= ' AND ' . $column_name . ' <= $' . count($values);
97 array_push($values, '%' . str_replace(array('\\', '_', '%'), array('\\\\', '\\_', '\\%'), $keyword) . '%');
98 $keyword_index = '$' . count($values);
99 array_push($values, ltrim($keyword, 'r'));
100 $revision_index = '$' . count($values);
102 AND ((committer_name LIKE $keyword_index OR committer_account LIKE $keyword_index) OR commit_revision = $revision_index)";
105 $commits = $db->query_and_fetch_all($statements . ' ORDER BY commit_time, commit_order', $values);
106 if (!is_array($commits))
107 exit_with_error('FailedToFetchCommits', array('repository' => $repository_id, 'first' => $first, 'second' => $second));
108 foreach ($commits as &$commit)
109 $commit['time'] = Database::to_js_time($commit['time']);
113 function format_commit($commit_row, $committer_row) {
115 'id' => $commit_row['commit_id'],
116 'revision' => $commit_row['commit_revision'],
117 'parent' => $commit_row['commit_parent'],
118 'time' => Database::to_js_time($commit_row['commit_time']),
119 'authorName' => $committer_row ? $committer_row['committer_name'] : null,
120 'authorEmail' => $committer_row ? $committer_row['committer_account'] : null,
121 'message' => $commit_row['commit_message']
125 main(array_key_exists('PATH_INFO', $_SERVER) ? explode('/', trim($_SERVER['PATH_INFO'], '/')) : array());