Finish issue #22 - Query on Log Messages.

Add the ability to query the commit database by log message comment in
addition to the existing query parameters.

Patch by: David Skyba <davidskyba@users.sourceforge.net>

* lib/cvsdb.py
  (CheckinDatabase.CreateSQLQueryString): Add support for filtering
    query results by log message.
  (CheckinDatabaseQuery.__init__): Add new comment_list member.
  (CheckinDatabaseQuery.SetComment): New.

* lib/viewvc.py
  (_legal_params): Add 'comment' and 'comment_match' as valid query
    parameters.
  (view_queryform): Populate new 'comment' and 'comment_match' data
    dictionary items.
  (english_query, view_query): Handle the new 'comment' and
    'comment_match' query items.

* templates/query_form.ezt
  Add UI for filtering queries by log message.

* docs/url-reference.html
  (Query View): Note new comment= and comment_match= URL parameters.

* docs/template-authoring-guide.html
  (variables-query_form): Note new comment and comment_match data
    dictionary items.





git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1509 8cb11bc2-c004-0410-86c3-e597b4017df7
remotes/options-overhaul
cmpilato 2007-01-23 16:22:40 +00:00
parent c3aabd8b7c
commit 79fe3a2919
5 changed files with 72 additions and 1 deletions

View File

@ -1726,6 +1726,18 @@ td {
Valid values: <tt>exact</tt>, <tt>like</tt>, <tt>glob</tt>,
<tt>regex</tt>, <tt>notregex</tt>.</td>
</tr>
<tr class="varlevel1">
<td class="varname">comment</td>
<td>String</td>
<td>Query string for filtering results by log message.</td>
</tr>
<tr class="varlevel1">
<td class="varname">comment_match</td>
<td>String</td>
<td>Type of match to perform with <var>comment</var> query string. Possible
values: <tt>exact</tt>, <tt>like</tt>, <tt>glob</tt>,
<tt>regex</tt>, <tt>notregex</tt>.</td>
</tr>
<tr class="varlevel1">
<td class="varname">date</td>
<td>String</td>

View File

@ -999,6 +999,16 @@ th.caption {
<td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td>
</tr>
<tr>
<td><code>comment=<var>COMMENT</var></code></td>
<td>optional</td>
<td>log message query string</td>
</tr>
<tr>
<td><code>comment_match=<var>COMMENT_MATCH</var></code></td>
<td>optional</td>
<td>"exact" "like" "glob" "regex" or "notregex" determining type of log message match</td>
</tr>
<tr>
<td><code>querysort=SORT</code></td>
<td>optional</td>

View File

@ -337,6 +337,12 @@ class CheckinDatabase:
temp = self.SQLQueryListString("people.who", query.author_list)
condList.append(temp)
if len(query.comment_list):
tableList.append(("descs", "(checkins.descid=descs.id)"))
temp = self.SQLQueryListString("descs.description",
query.comment_list)
condList.append(temp)
if query.from_date:
temp = "(checkins.ci_when>=\"%s\")" % (str(query.from_date))
condList.append(temp)
@ -661,6 +667,7 @@ class CheckinDatabaseQuery:
self.directory_list = []
self.file_list = []
self.author_list = []
self.comment_list = []
## date range in DBI 2.0 timedate objects
self.from_date = None
@ -691,6 +698,9 @@ class CheckinDatabaseQuery:
def SetAuthor(self, author, match = "exact"):
self.author_list.append(QueryEntry(author, match))
def SetComment(self, comment, match = "exact"):
self.comment_list.append(QueryEntry(comment, match))
def SetSortMethod(self, sort):
self.sort = sort

View File

@ -671,6 +671,8 @@ _legal_params = {
'file_match' : _re_validate_alpha,
'who' : _validate_regex,
'who_match' : _re_validate_alpha,
'comment' : _validate_regex,
'comment_match' : _re_validate_alpha,
'querysort' : _re_validate_alpha,
'date' : _re_validate_alpha,
'hours' : _re_validate_number,
@ -3154,6 +3156,8 @@ def view_queryform(request):
data['file_match'] = request.query_dict.get('file_match', 'exact')
data['who'] = request.query_dict.get('who', '')
data['who_match'] = request.query_dict.get('who_match', 'exact')
data['comment'] = request.query_dict.get('comment', '')
data['comment_match'] = request.query_dict.get('comment_match', 'exact')
data['querysort'] = request.query_dict.get('querysort', 'date')
data['date'] = request.query_dict.get('date', 'hours')
data['hours'] = request.query_dict.get('hours', '2')
@ -3208,7 +3212,8 @@ def english_query(request):
ret.append(' <em>%s</em> ' % request.server.escape(dir))
file = request.query_dict.get('file', '')
if file:
if len(ret) != 1: ret.append('and ')
if len(ret) != 1:
ret.append('and ')
ret.append('to file <em>%s</em> ' % request.server.escape(file))
who = request.query_dict.get('who', '')
branch = request.query_dict.get('branch', '')
@ -3216,6 +3221,9 @@ def english_query(request):
ret.append('on branch <em>%s</em> ' % request.server.escape(branch))
else:
ret.append('on all branches ')
comment = request.query_dict.get('comment', '')
if comment:
ret.append('with comment <i>%s</i> ' % htmlify(comment))
if who:
ret.append('by <em>%s</em> ' % request.server.escape(who))
date = request.query_dict.get('date', 'hours')
@ -3381,6 +3389,8 @@ def view_query(request):
file_match = request.query_dict.get('file_match', 'exact')
who = request.query_dict.get('who', '')
who_match = request.query_dict.get('who_match', 'exact')
comment = request.query_dict.get('comment', '')
comment_match = request.query_dict.get('comment_match', 'exact')
querysort = request.query_dict.get('querysort', 'date')
date = request.query_dict.get('date', 'hours')
hours = request.query_dict.get('hours', '2')
@ -3400,6 +3410,7 @@ def view_query(request):
if not match_types.has_key(branch_match): branch_match = 'exact'
if not match_types.has_key(file_match): file_match = 'exact'
if not match_types.has_key(who_match): who_match = 'exact'
if not match_types.has_key(comment_match): comment_match = 'exact'
if not sort_types.has_key(querysort): querysort = 'date'
if not date_types.has_key(date): date = 'hours'
mindate = parse_date(mindate)
@ -3438,6 +3449,8 @@ def view_query(request):
query.SetFile(file, file_match)
if who:
query.SetAuthor(who, who_match)
if comment:
query.SetComment(comment, comment_match)
query.SetSortMethod(querysort)
if date == 'hours':
query.SetFromDateHoursAgo(int(hours))

View File

@ -102,6 +102,32 @@ Browse Directory</a></p>
</label>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Comment:</th>
<td>
<input type="text" name="comment" value="[comment]" /><br />
<label for="comment_match_exact">
<input type="radio" name="comment_match" id="comment_match_exact"
value="exact" [is comment_match "exact"]checked=""[end] />
Exact match
</label>
<label for="comment_match_glob">
<input type="radio" name="comment_match" id="comment_match_glob"
value="glob" [is comment_match "glob"]checked=""[end] />
Glob pattern match
</label>
<label for="comment_match_regex">
<input type="radio" name="comment_match" id="comment_match_regex"
value="regex" [is comment_match "regex"]checked=""[end] />
Regex match
</label>
<label for="comment_match_notregex">
<input type="radio" name="comment_match" id="comment_match_notregex"
value="notregex" [is comment_match "notregex"]checked=""[end] />
Regex doesn't match
</label>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Sort By:</th>
<td>