一个用于搜索SVN仓库的LogParser输入插件





0/5 (0投票)
使用SharpSvn查询SVN仓库的自定义LogParser输入插件示例
摘要
以下是如何编写自定义LogParser输入插件的示例,使用SharpSvn查询SVN仓库。
下载LogParser.Svn项目。 你需要Visual Studio 2010 Express来构建它。 确保项目属性的构建选项卡中选中“注册COM互操作”。 你还需要下载最新版本的SharpSvn并更新项目中的引用。
任何对示例的引用都指的是以下命令行
LogParser.exe -rtp:-1 -i:COM -iProgID:LogParser.Svn.SvnLogParserInputContext
-iCOMParams:startDate=2010-01-01 "Select Count(1),
Author From http://my.svn/repo/trunk Group By Author Order By Count(1)"
首先,在Visual Studio中创建一个新的“类库”项目。 我将其命名为LogParser.Svn
。
接下来,我们需要创建COM接口和我们的代码将使用的enum
的副本
public enum FieldType : int
{
Integer = 1,
Real = 2,
String = 3,
Timestamp = 4,
Null = 5,
};
public interface ILogParserInputContext
{
void OpenInput(string from);
int GetFieldCount();
string GetFieldName(int index);
FieldType GetFieldType(int index);
bool ReadRecord();
object GetValue(int index);
void CloseInput(bool abort);
}
现在我们需要一个实现上述接口的类。 让我们从OpenInput
方法开始。 该方法将接收一个string
,该字符串输入到传递给LogParser
的查询中,代表“FROM
”语句。 采用上面的命令行,它将接收一个值为“http://my.svn/repo/trunk”。
public void OpenInput(string from)
{
// System.Diagnostics.Debugger.Launch();
_client = new SvnClient();
_repository = from;
SvnLogArgs args = new SvnLogArgs();
if (_start.HasValue)
{
if (_end.HasValue)
{
args.Range = new SvnRevisionRange(_start.Value, _end.Value);
}
else
{
args.Range = new SvnRevisionRange(new SvnRevision(_start.Value), SvnRevision.Head);
}
}
else if (_end.HasValue)
{
args.Range = new SvnRevisionRange(SvnRevision.Zero, new SvnRevision(_end.Value));
}
if (_startDate.HasValue)
{
if (_endDate.HasValue)
{
args.Range = new SvnRevisionRange(_startDate.Value, _endDate.Value);
}
else
{
args.Range = new SvnRevisionRange(new SvnRevision
(_startDate.Value), SvnRevision.Head);
}
}
else if (_endDate.HasValue)
{
args.Range = new SvnRevisionRange(SvnRevision.Zero, new SvnRevision(_endDate.Value));
}
_results = new List<object[]>();
_client.Log(new Uri(_repository), args, delegate(object sender, SvnLogEventArgs e)
{
if (_splitFiles)
{
foreach (SvnChangeItem i in e.ChangedPaths)
{
object[] result = new object[6];
result[0] = e.Author;
result[1] = e.LogMessage;
result[2] = e.Revision;
result[3] = e.Time;
result[4] = i.Path;
_results.Add(result);
}
}
else
{
object[] result = new object[6];
result[0] = e.Author;
result[1] = e.LogMessage;
result[2] = e.Revision;
result[3] = e.Time;
StringBuilder paths = new StringBuilder();
foreach (SvnChangeItem i in e.ChangedPaths)
{
paths.AppendFormat("{0};", i.Path);
}
result[4] = paths.ToString();
_results.Add(result);
}
});
}
首先,上面的代码创建了一个新的SvnClient
对象,我们将使用它来查看日志消息。 接下来,我们创建一个SvnLogArgs
对象,并设置我们想要的修订范围。 最后,我们调用SvnClient.Log
。 在委托中,我们收到与我们的SvnLogArgs
对象匹配的每个日志条目。 然后,我们创建一个值数组并将它们存储在List
中。 理想情况下,我们应该只准备接收一个值,然后在每次调用ReadRecord
时接收每个条目,但我还没有来得及这样做(但更改代码以使其以这种方式工作应该不会太难)。
接下来的几个方法非常简单明了
public int GetFieldCount()
{
return 5;
}
public string GetFieldName(int index)
{
switch (index)
{
case 0:
return "Author";
case 1:
return "LogMessage";
case 2:
return "Revision";
case 3:
return "Time";
case 4:
return "ChangedPaths";
}
return null;
}
public FieldType GetFieldType(int index)
{
switch (index)
{
case 0:
return FieldType.String;
case 1:
return FieldType.String;
case 2:
return FieldType.Integer;
case 3:
return FieldType.Timestamp;
case 4:
return FieldType.String;
}
return FieldType.Null;
}
public bool ReadRecord()
{
return ++_rowNumber < _results.Count;
}
public object GetValue(int index)
{
return _results[_rowNumber][index];
}
public void CloseInput(bool abort)
{
_client.Dispose();
}
GetFieldCount
返回你的解析器可以返回的字段数量。 GetFieldName
返回给定索引的字段名称。 GetFieldType
返回给定索引的字段类型。 ReadRecord
是你的插件应该前进到下一个记录的地方,如果找到另一个记录则返回true
。 GetValue
返回当前记录的指定字段的值。 CloseInput
在最后调用,你可以在这里进行任何需要的清理。
你还可以创建一些只写属性,这些属性可以使用-iCOMParams:prop=value
在命令行上设置。 请参阅附带的代码以获取示例。
我希望这能帮助那些尝试开始使用SharpSvn或编写自己的LogParser输入插件的人。