XQuery/Subversion
您希望能够访问 Subversion (SVN) 存储库,包括将存储库的文件直接检出到 eXist 数据库中,以及使用 XQuery 将更改后的文件提交回存储库。
eXist 1.5 的最前沿开发版本中添加了一个 Subversion XQuery 模块。您可以使用它查询远程 Subversion 服务器,甚至将远程存储库检出以将存储库的内容存储在数据库中。(如果您确实检出了存储库,请注意,Subversion 存储库的文件,包括其许多“.svn”文件,将直接存储在您的数据库中。)截至 2011 年 5 月,Subversion 模块可以执行大多数,但不是全部,常见的 Subversion 功能。
与所有默认情况下未启用的 eXist 扩展一样,您需要指示 eXist 的构建过程包含该扩展。
您应该首先将文件$EXIST_HOME/extensions/build.properties复制到一个名为 $EXIST_HOME/extensions/local.build.properties 的新文件中。这个本地文件将被构建过程使用,但会被您的 Subversion 客户端忽略,这样您就不会意外地将其提交到 eXist 存储库中。
您现在应该找到以下行
#SVN extension include.feature.svn = false
将false更改为true
include.feature.svn = true
保存 local.build.properties 文件。有了这些更改,您现在必须重建(即重新编译)eXist,以便 Subversion 扩展包含在 eXist 的 jar 文件中。
为了确保模块在您启动 eXist 时可用,请在您的 $EXIST_HOME/conf.xml 文件中取消以下行的注释
<module uri="http://exist-db.org/xquery/versioning/svn" class="org.exist.versioning.svn.xquery.SVNModule" />
保存 conf.xml。现在您可以启动 eXist,并且 Subversion 模块现在可以供您使用。您可以在 https://127.0.0.1:8080/exist/admin/admin.xql?panel=fundocs 处构建 Subversion 功能文档,然后访问 https://127.0.0.1:8080/exist/functions/subversion。
您现在应该能够测试 Subversion XQuery 函数。这应该与 eXist 演示站点上的函数列表非常相似:http://demo.exist-db.org/exist/xquery/functions.xql
可以通过 HTTP 和 HTTPS 访问 Subversion 存储库,既可以通过匿名访问,也可以通过用户名/密码身份验证访问。
以下功能已测试有效
- subversion:checkout($repository-uri as xs:string, $database-path as xs:string) xs:long
- subversion:checkout($repository-uri as xs:string, $database-path as xs:string, $login as xs:string, $password as xs:string) xs:long
- subversion:get-latest-revision-number($repository-uri as xs:string, $login as xs:string, $password as xs:string) xs:long
- subversion:info($database-path as xs:string) element()
- subversion:list($repository-uri as xs:string) element()
- subversion:log($repository-uri as xs:string, $login as xs:string, $password as xs:string, $start-revision as xs:integer?, $end-revision as xs:integer?) element()
- subversion:status($database-path as xs:string) element()
- subversion:update($database-path as xs:string) xs:long
- subversion:update($database-path as xs:string, $login as xs:string, $passwrod as xs:string) xs:long
- subversion:add($database-path as xs:string) empty()
以下功能在某些情况下有效,但在某些提交大小情况下存在缓冲区错误
- subversion:commit($database-path as xs:string, $message as xs:string?, $login as xs:string, $password as xs:string) xs:long
以下功能尚未确认有效,仍在测试中
- subversion:clean-up($database-path as xs:string) empty()
- subversion:lock($database-path as xs:string, $message as xs:string?) empty()
- subversion:revert($database-path as xs:string) empty()
- subversion:unlock($database-path as xs:string) empty()
subversion:get-latest-revision-number() 函数查询远程 SVN 存储库,返回最新的修订版号。例如
xquery version "1.0";
import module namespace subversion = "http://exist-db.org/xquery/versioning/svn";
let $repository-uri := xs:anyURI('https://exist.svn.sourceforge.net/svnroot/exist/trunk/eXist/webapp/eXide')
let $username := ''
let $password := ''
return
subversion:get-latest-revision-number($repository-uri, $username, $password)
此查询返回以下结果
14458
从 Subversion 检出资源后,您可以本地查询该资源,并了解更多信息。
subversion:info('/db/apps/faqs/data')
这将返回
<info uri="/db/cms/apps/faqs/data">
<info local-path="/db/apps/faqs/data"
URL="https://www.example.com/repo/trunk/db/apps/faq/data"
Repository-UUID="db6794ef-7b42-44a9-8912-f63d0efeae0f"
Revision="10" Node-Kind="dir" Schedule="normal"
Last-Changed-Author="dmccreary" Last-Changed-Revision="8"
Last-Changed-Date="Thu Sep 01 15:03:04 CDT 2011"/>
subversion:list() 函数列出远程存储库的内容,将结果作为 XML 节点返回
xquery version "1.0";
let $repository-uri := xs:anyURI('https://exist.svn.sourceforge.net/svnroot/exist/trunk/eXist/webapp/scripts/')
return
subversion:list($repository-uri)
此脚本将返回以下结果
<entries>
<entry type="directory">edit_area</entry>
<entry type="directory">jquery</entry>
<entry type="directory">openid-selector</entry>
<entry type="directory">syntax</entry>
<entry type="directory">yui</entry>
<entry type="file">fundocs.js</entry>
<entry type="file">main.js</entry>
<entry type="file">prototype.js</entry>
</entries>
subversion:log() 函数查询远程 SVN 存储库,将更改日志作为 XML 节点返回。例如,此查询将返回显示两个任意修订版号之间的更改日志(请注意,用空节点()替换 $start-revision 和/或 $end-revision 将返回更开放的修订版日志)
xquery version "1.0";
let $repository-uri := xs:anyURI('https://exist.svn.sourceforge.net/svnroot/exist/trunk/eXist/webapp/eXide')
let $username := ''
let $password := ''
let $start-revision := 14300
let $end-revision := 14350
return
subversion:log($repository-uri, $username, $password, $start-revision, $end-revision)
此查询的结果如下(请注意,@revtype 值为“A”表示添加项,“D”表示删除项,“M”表示修改项,“R”表示替换项)
<log uri="https://exist.svn.sourceforge.net/svnroot/exist/trunk/eXist/webapp/eXide" start="14300">
<entry rev="14331" author="wolfgang_m" date="2011-04-29T07:00:54.297-04:00">
<message>[feature] eXide - a web-based XQuery IDE for eXist. Features: fast syntax
highlighting, ability to edit huge XQuery files, code completion for functions and
variables, code templates, powerful navigation, on-the-fly compilation, generation of
app skeletons, integration with app repository... This is the initial checkin of eXide.</message>
<paths>
<path revtype="A">/trunk/eXist/webapp/eXide/templates</path>
<path revtype="A">/trunk/eXist/webapp/eXide/collections.xql</path>
<path revtype="A">/trunk/eXist/webapp/eXide/session.xql</path>
....etc....
<path revtype="A">/trunk/eXist/webapp/eXide/scripts/ace/cockpit.js</path>
<path revtype="A">/trunk/eXist/webapp/eXide/index.html</path>
</paths>
</entry>
<entry rev="14346" author="wolfgang_m" date="2011-04-30T08:35:23.395-04:00">
<message>[website] eXide: fixed completion popup window (support mouse, extra "close" link
if popup looses focus); improved auto-indent in editor after { and (.</message>
<paths>
<path revtype="M">/trunk/eXist/webapp/eXide/src/mode-xquery.js</path>
<path revtype="M">/trunk/eXist/webapp/eXide/src/util.js</path>
<path revtype="M">/trunk/eXist/webapp/eXide/eXide.css</path>
</paths>
</entry>
</log>
log 函数可以与 get-latest-revision-number 函数结合使用,以获取系统中的最后 10 条提交消息。
let $latest-version := subversion:get-latest-revision-number($repo-url, $svn-account, $svn-password)
(: if we have more than 10 revisions then get them all, else start with one :)
let $start :=
if ($latest-version gt 10)
then $latest-version - 10
else 1
return
<last-10-commit-messages>
{subversion:log($repo-url, $svn-account, $svn-password, $start , $latest-version)//*:message}
</last-10-commit-messages>
以下示例将 eXist 的“functions”应用程序检出到“/db/svn”集合中
xquery version "1.0";
let $repository-uri := xs:anyURI('https://exist.svn.sourceforge.net/svnroot/exist/trunk/eXist/webapp/functions/')
let $destination-path := '/db/svn'
let $version := subversion:checkout($repository-uri, $destination-path)
return
concat('Revision ', $version, ' successfully checked out to collection ', $destination-path)
这将返回
Revision 14457 successfully checked out to collection /db/svn
/db/svn 集合现在将包含以下文件
- .svn(集合)
- controller.xql
- filter.xql
- functions.xql
完成检出操作后,您就可以执行 subversion:commit() 或 subversion:add() 操作。
这两个函数都接收一个参数,即您要发送到 Subversion 服务器的数据库集合路径。
假设我们已经将仓库检出到 /db/svn 目录,我们可以使用 subversion:update() 函数将工作副本更新到最新版本。
xquery version "1.0";
let $working-copy := '/db/svn'
let $update := subversion:update($working-copy)
return
concat('Successfully updated to revision ', $update)
此脚本将返回以下结果
Successfully updated to revision 14457
您也可以通过使用 **subversion:update($working-copy, $user, $password)** 从安全站点获取更新。
subversion:status() 函数返回本地工作副本中文件的狀態。例如,假设您已将仓库 https://exist.svn.sourceforge.net/svnroot/exist/trunk/eXist/webapp/functions/ 检出到 /db/svn 集合,您可以使用以下查询获取其文件的狀態。
xquery version "1.0";
let $destination-path := '/db/svn'
return
subversion:status($destination-path)
结果将是
<status>
<entry status="normal" locked="false" working-revision="14490" last-changed-revision="13019" author="joewiz" path="/db/svn/controller.xql"/>
<entry status="normal" locked="false" working-revision="14490" last-changed-revision="10350" author="wolfgang_m" path="/db/svn/filter.xql"/>
<entry status="normal" locked="false" working-revision="14490" last-changed-revision="13019" author="joewiz" path="/db/svn/functions.xql"/>
<entry status="normal" locked="false" working-revision="14490" last-changed-revision="13019" author="joewiz" path="/db/svn"/>
</status>