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://:8080/exist/admin/admin.xql?panel=fundocs 處構建 Subversion 功能文件,然後訪問 https://: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>