HXQ 0.12.0 → 0.14.0
raw patch · 19 files changed
+304/−125 lines, 19 filesdep +editlinePVP ok
version bump matches the API change (PVP)
Dependencies added: editline
API changes (from Hackage documentation)
- Text.XML.HXQ.XQuery: xfile :: String -> IO XSeq
- Text.XML.HXQ.XQuery: xfileDB :: String -> Connection -> IO XSeq
- Text.XML.HXQ.XQuery: commit :: conn -> IO ()
+ Text.XML.HXQ.XQuery: commit :: Connection -> IO ()
- Text.XML.HXQ.XQuery: disconnect :: conn -> IO ()
+ Text.XML.HXQ.XQuery: disconnect :: Connection -> IO ()
- Text.XML.HXQ.XQuery: rollback :: conn -> IO ()
+ Text.XML.HXQ.XQuery: rollback :: Connection -> IO ()
Files
- HXQ.cabal +14/−14
- Main.hs +7/−5
- Makefile +18/−5
- Test2.hs +3/−8
- Test2a.hs +26/−0
- TestDBa.hs +26/−0
- compile +1/−1
- compile.bat +1/−1
- db.html +2/−2
- index.html +26/−17
- src/Readline.hs +20/−0
- src/Text/XML/HXQ/Compiler.hs +20/−7
- src/Text/XML/HXQ/Functions.hs +111/−15
- src/Text/XML/HXQ/Interpreter.hs +7/−27
- src/Text/XML/HXQ/XQuery.hs +9/−6
- src/Text/XML/HXQ/XTree.hs +4/−3
- src/noDB/Text/XML/HXQ/OptionalDB.hs +6/−3
- src/readline/System/Console/Readline.hs +0/−10
- src/withDB/Text/XML/HXQ/DB.hs +3/−1
HXQ.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: >= 1.2 Name: HXQ-Version: 0.12.0+Version: 0.14.0 Synopsis: A Compiler from XQuery to Haskell Description: HXQ is a fast and space-efficient compiler from XQuery (the standard@@ -23,12 +23,13 @@ src/withDB/Text/XML/HXQ/OptionalDB.hs src/mysql/Connect.hs src/sqlite/Connect.hs- src/readline/System/Console/Readline.hs Makefile XQueryParser.y Test1.hs Test2.hs+ Test2a.hs TestDB.hs+ TestDBa.hs TestDB2.hs TestDBLP1.hs TestDBLP2.hs@@ -64,17 +65,17 @@ Library Exposed-Modules: Text.XML.HXQ.XQuery- Other-Modules: Text.XML.HXQ.XTree, Text.XML.HXQ.Functions, Text.XML.HXQ.Compiler,- Text.XML.HXQ.Interpreter, Text.XML.HXQ.Parser, Text.XML.HXQ.Optimizer,- Text.XML.HXQ.OptionalDB, HXML, DTD, LLParsing, TreeBuild, XMLParse,- ETree, Misc, Tree, XMLScanner, AssocList, PrintXML, XML+ Other-Modules: Readline, HXML, DTD, LLParsing, TreeBuild, XMLParse,+ ETree, Misc, Tree, XMLScanner, AssocList, PrintXML, XML, Text.XML.HXQ.XTree+ Text.XML.HXQ.Functions, Text.XML.HXQ.Compiler, Text.XML.HXQ.Interpreter,+ Text.XML.HXQ.Optimizer, Text.XML.HXQ.OptionalDB, Text.XML.HXQ.Parser hs-source-dirs: . src src/hxml-0.2 Build-Depends: base, haskell98, array, template-haskell- if os(windows)- hs-source-dirs: src/readline- Other-Modules: System.Console.Readline- else+ ghc-options: -funfolding-use-threshold=16+ if impl(ghc < 6.10) Build-Depends: readline+ else+ Build-Depends: editline if flag(mysql) Other-Modules: Text.XML.HXQ.DB, Connect Build-Depends: HDBC < 1.1.5, HDBC-odbc@@ -91,11 +92,10 @@ Executable xquery Main-is: Main.hs hs-source-dirs: . src src/hxml-0.2- if os(windows)- hs-source-dirs: src/readline- Other-Modules: System.Console.Readline- else+ if impl(ghc < 6.10) Build-Depends: readline+ else+ Build-Depends: editline if flag(mysql) Build-Depends: HDBC < 1.1.5, HDBC-odbc hs-source-dirs: src/withDB, src/mysql
Main.hs view
@@ -2,7 +2,7 @@ - - The main program of the XQuery interpreter - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)-- Date: 12/06/2008+- Date: 12/19/2008 - ---------------------------------------------------------------} @@ -16,14 +16,15 @@ #else import qualified Control.Exception as C #endif-import Text.XML.HXQ.Functions(functions)-import Text.XML.HXQ.Interpreter(evalInput,xqueryE) import Text.XML.HXQ.XQuery+import Text.XML.HXQ.Functions+import Text.XML.HXQ.Interpreter(evalInput,xqueryE,xfileDB) + type E = C.Exception -version = "0.12.0"+version = "0.14.0" parseEnv :: [String] -> [(String,String)]@@ -59,7 +60,8 @@ putStrLn "Without an xquery-file, it reads and evaluates the input using the HXQ interpreter." putStrLn " The input may be an XQuery or a 'declare variable' or a 'declare function'." putStrLn " To write an XQuery in multiple lines, wrap it in {}"- putStrLn ("Functions: "++(foldr (\(f,_,_) r -> f++" "++r) "" functions))+ putStrLn ("Functions: "++(foldr (\(f,_,_) r -> f++" "++r) "" systemFunctions))+ putStrLn ("Path Steps: "++(foldr (\(f,_) r -> f++" "++r) "" pathFunctions)) _ -> case lookup "c" env of Just file -> do query <- readFile file let qf = map (\c -> if c=='\"' then '\'' else c)
Makefile view
@@ -9,8 +9,8 @@ endif parser = src/Text/XML/HXQ/Parser.hs-ghc = ghc -O2 ${args}-src = * src/hxml-0.2/* src/noDB/Text/XML/HXQ/* src/withDB/Text/XML/HXQ/* src/readline/System/Console/* src/Text/XML/HXQ/* src/mysql/* src/sqlite/*+ghc = ghc -O2 -funfolding-use-threshold=16 ${args}+src = * src/hxml-0.2/* src/noDB/Text/XML/HXQ/* src/withDB/Text/XML/HXQ/* src/* src/Text/XML/HXQ/* src/mysql/* src/sqlite/* # xquery interpreter all: $(parser) Main.hs@@ -26,8 +26,13 @@ test2: $(parser) Test2.hs $(ghc) --make Test2.hs -o a.out- time ./a.out +RTS -H20m+ time ./a.out +RTS -H2m +# uses quasi-quotes (for ghc >= 6.9 only)+test2a: $(parser) Test2a.hs+ $(ghc) --make Test2a.hs -o a.out+ time ./a.out +RTS -H2m+ test3: $(parser) TestDB.hs $(ghc) --make TestDB.hs -o a.out ./a.out@@ -48,14 +53,22 @@ ghci: $(parser) ghci -fth ${args} Main.hs +# heap profiling+profile: $(parser) Test2.hs+ ghc -O2 -funfolding-use-threshold=16 -isrc -isrc/hxml-0.2 -isrc/noDB --make Test2.hs -o a.out+ ghc -O2 -funfolding-use-threshold=16 -isrc -isrc/hxml-0.2 -isrc/noDB -prof -auto-all -osuf p_o --make Test2.hs -o a.out+ time ./a.out +RTS -hc+ hp2ps -color a.out.hp+ # create the cabal distribution cabal: $(parser)- runhaskell Setup.lhs configure --ghc -fmysql --user --prefix=$(HOME)+ runhaskell Setup.lhs configure runhaskell Setup.lhs build+ runhaskell Setup.lhs haddock runhaskell Setup.lhs sdist clean:- /bin/rm -f xquery hxqc Temp.hs a.out $(addsuffix .hi,$(src)) $(addsuffix .o,$(src))+ /bin/rm -f xquery hxqc Temp.hs a.out $(addsuffix .hi,$(src)) $(addsuffix .o,$(src)) $(addsuffix .p_o,$(src)) distclean: clean runhaskell Setup.lhs clean
Test2.hs view
@@ -1,9 +1,10 @@ {-------------------------------------------------------------- - - Testing the XQuery compiler on a large file-- Download dblp.xml from http://dblp.uni-trier.de/xml/+- Download dblp.xml.gz from http://dblp.uni-trier.de/xml/+- and uncompress it in the data directory. - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)-- Date: 07/24/2008+- Date: 12/10/2008 - ---------------------------------------------------------------} @@ -14,17 +15,11 @@ import Text.XML.HXQ.XQuery -f(x,y) = $(xq "<a>{$x,$y}</a>")-- main = do a <- $(xq ("<result>{ " ++" for $x at $i in doc('data/dblp.xml')//inproceedings " ++" where $x/author = 'Leonidas Fegaras' "- ++" order by $x/year descending " ++" return <paper>{ $i, $x/booktitle/text(), " ++" ':', $x/title/text() " ++" }</paper> " ++" }</result> ")) putXSeq a- b <- $(xq "f($a/paper[10],$a/paper[8])")- putXSeq b
+ Test2a.hs view
@@ -0,0 +1,26 @@+{--------------------------------------------------------------+-+- Testing the XQuery compiler on a large file+- Download dblp.xml.gz from http://dblp.uni-trier.de/xml/+- and uncompress it in the data directory.+- Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)+- Date: 12/14/2008+-+---------------------------------------------------------------}++{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}++module Main where++import Text.XML.HXQ.XQuery+++main = do a <- [$qx| <result>{+ for $x at $i in doc('data/dblp.xml')//inproceedings+ where $x/author = 'Leonidas Fegaras'+ return <paper>{ $i, $x/booktitle/text(),+ ':', $x/title/text()+ }</paper>+ }</result> |]+ putXSeq a
+ TestDBa.hs view
@@ -0,0 +1,26 @@+{--------------------------------------------------------------+-+- A main program to test XQuery connected to a Sqlite database+- To create the database load the file data/company.sql in sqlite3+-+- Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)+- Date: 12/14/2008+-+---------------------------------------------------------------}++{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}++module Main where++import Text.XML.HXQ.XQuery+++main = do _db <- connect "hxq"+ e <- [$qx| for $r in sql(' select e.fname, d.dname+ from employee e, department d+ where e.dno = d.dnumber+ and e.lname = ? ',+ 'English')+ return <result>{$r/fname,$r/dname}</result> |]+ putXSeq e
compile view
@@ -2,4 +2,4 @@ xquery -c $1 if [$2 == ""]; then file="a.out"; else file=$2; fi-ghc -O2 --make Temp.hs -o $file+ghc -O2 -v0 --make Temp.hs -o $file
compile.bat view
@@ -10,4 +10,4 @@ :Exit set FILE="a.exe" :End-ghc -O2 --make Temp.hs -o %FILE%+ghc -O2 -v0 --make Temp.hs -o %FILE%
db.html view
@@ -3,7 +3,7 @@ <body> <center> <h1>HXQ with Database Connectivity</h1>-<h3>Download <a href="/HXQ-0.12.0.tar.gz">HXQ-0.12.0.tar.gz</a></h3>+<h3>Download <a href="/HXQ-0.14.0.tar.gz">HXQ-0.14.0.tar.gz</a></h3> </center> <p> <h2>Installation Instructions (HXQ with database connectivity)</h2>@@ -195,4 +195,4 @@ <p> <hr> <p>-<address>Last modified: 12/06/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 12/19/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
index.html view
@@ -3,7 +3,7 @@ <body> <center> <h1>HXQ: A Compiler from XQuery to Haskell</h1>-<h3>Download <a href="/HXQ-0.12.0.tar.gz">HXQ-0.12.0.tar.gz</a></h3>+<h3>Download <a href="/HXQ-0.14.0.tar.gz">HXQ-0.14.0.tar.gz</a></h3> </center> <p> <h2>Description</h2>@@ -11,7 +11,8 @@ HXQ is a fast and space-efficient translator from <a href="http://www.w3.org/XML/Query/">XQuery</a> (the standard query language for XML) to embedded Haskell code. The translation is-based on Haskell templates. HXQ takes full advantage of Haskell's lazy+based on <a href="http://haskell.org/haskellwiki/Template_Haskell">Haskell templates</a>.+HXQ takes full advantage of Haskell's lazy evaluation to keep in memory only those parts of XML data needed at each point of evaluation, thus performing stream-based evaluation for forward queries (queries that do not contain backward steps). This@@ -39,14 +40,14 @@ Linux, MAC OS X, and Windows XP. The simplest installation is without database connectivity (ie, it can only process XQueries against XML text documents). If you want database connectivity-(over mysql or sqlite relational databases), look at the <a href="db.html">installation instructions with database connectivity</a>.+(over mysql or sqlite relational databases), look at the <a href="db.html">installation instructions for database connectivity</a>. <p> First, you need to install the Glasgow Haskell Compiler, <a href="http://www.haskell.org/ghc/">ghc</a>. Optionally, if you want to modify the XQuery parser, you need to install the parser generator for Haskell, <a href="http://www.haskell.org/happy/">happy</a>. Then,-download <a href="/HXQ-0.12.0.tar.gz">HXQ version 0.12.0</a> and untar+download <a href="/HXQ-0.14.0.tar.gz">HXQ version 0.14.0</a> and untar it (using <tt>tar xfz</tt> on Linux or <a href="http://www.7-zip.org/">7z x</a> on Windows). Then, you execute the following commands inside the HXQ directory:@@ -56,8 +57,6 @@ runhaskell Setup.lhs install </pre> On linux, the last command must be run as root.-If you get an error during configuration that the readline package is missing, install-<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/readline">readline</a> before HXQ. HXQ consists of the executable <tt>xquery</tt>, which is the XQuery interpreter, and the HXQ library. To use the HXQ library in a Haskell program, simply <tt>import Text.XML.HXQ.XQuery</tt>.@@ -68,7 +67,11 @@ <h2>Current Status</h2> <p> HXQ supports most essential XQuery features, although some system-functions are missing (but are easy to add). To see the list of+functions are missing (but are easy to add). +Note that HXQ is a proof-of-concept (prototype) implementation; it's not+fully compliant with the W3C specs. One may use HXQ as a basis+for a fully compliant XQuery implementation (conforming to W3C test suits),+but currently I do not have the time to do so. To see the list of supported system functions, run <tt>xquery -help</tt> . HXQ does not have static typechecking; it leaves all checking to Haskell. In addition, the XQuery semantics requires duplicate elimination and@@ -96,7 +99,8 @@ The complete XQuery syntax in HXQ is described in <a href="hxq-manual.pdf">hxq-manual.pdf</a>. Here some tutorials on <a href="http://lambda.uta.edu/cse6339/queries2.pdf">XPath</a> and <a href="http://lambda.uta.edu/cse6339/xquery2.pdf">XQuery</a>.-Here is a nice <a href="http://www.dbis.ethz.ch/education/ws0708/xml_db_ws2007">course on XML and XQuery</a>.+Here are two relevant courses on XML and databases at <a href="http://www.stanford.edu/class/cs345b/">Stanford</a>+and <a href="http://www.dbis.ethz.ch/education/ws0708/xml_db_ws2007">ETH</a>. <p> <h2>Using the Compiler</h2> <p>@@ -135,6 +139,8 @@ </pre> Another example, can be found in <a href="Test1.hs">Test1.hs</a>. You compile it using <tt>ghc --make Test1.hs -o a.out</tt>.+Using the latest ghc (version >= 6.9), one may use <a href="http://haskell.org/haskellwiki/Quasiquotation">quasi-quotations</a>+instead of strings, as is shown in <a href="Test2a.hs">Test2a.hs</a>. <p> You can compile an XQuery file into a Haskell program (<tt>Temp.hs</tt>) using <tt>xquery -c file</tt>. Or better, you can@@ -149,24 +155,27 @@ <p> The HXQ interpreter is far more slower than the compiler; use it only if you need to evaluate ad-hoc XQueries read from input or from files.-The main functions are:-<ul>-<li> <tt>xquery :: String -> IO XSeq</tt> -- Evaluates an XQuery in a string-<li> <tt>xfile :: String -> IO XSeq</tt> -- Evaluates an XQuery in a file-</ul>+The only function is:+<pre>+xquery :: String -> IO XSeq+</pre>+which evaluates an XQuery in a string. The HXQ interpreter doesn't recognize Haskell variables and functions (but you may declare XQuery variables and functions using the XQuery-'declare' syntax). The main HXQ program, called <tt>xquery</tt>,+'declare' syntax). The main HXQ program, called <tt>xquery</tt>, evaluates an XQuery in a file using the interpreter. For example: <pre> xquery data/q1.xq </pre> Without an argument, it reads and evaluates XQueries and variable/function declarations from input. With <tt>xquery -p-xpath-query xml-file</tt> you evaluate an XPath query against an XML-file, eg. <tt>xquery -p "//inproceedings[100]" data/dblp.xml</tt>.+xpath-query xml-file</tt> you can evaluate an XPath query against an XML+file. For example, +<pre>+xquery -p "//inproceedings[100]" data/dblp.xml+</pre> With <tt>xquery -help</tt> you get the list of system functions and usage information. <p> <hr> <p>-<address>Last modified: 12/06/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 12/19/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
+ src/Readline.hs view
@@ -0,0 +1,20 @@+{-# OPTIONS -cpp #-}++module Readline (readline,addHistory) where++#if __GLASGOW_HASKELL__ >= 609+import System.Console.Editline.Readline+#else+import System.Console.Readline+#endif++{-+import System.IO++readline prompt = do putStr prompt+ hFlush stdout+ line <- getLine+ return (Just line)++addHistory stmt = return ""+-}
src/Text/XML/HXQ/Compiler.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 02/15/08, last update: 12/06/08+- Creation: 02/15/08, last update: 12/19/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -13,22 +13,27 @@ - --------------------------------------------------------------------------------------} -+{-# OPTIONS -cpp #-} {-# LANGUAGE TemplateHaskell #-} -module Text.XML.HXQ.Compiler where+module Text.XML.HXQ.Compiler+ ( xe, xq, xqdb, maxPosition, containsLast, qName, qx,+ parent_error, pathPosition, liftIOSources ) where +import Text.XML.HXQ.Parser+import Text.XML.HXQ.XTree+import Text.XML.HXQ.OptionalDB import Control.Monad import Char(toLower) import List(sortBy) import XMLParse(parseDocument)-import Text.XML.HXQ.Parser-import Text.XML.HXQ.XTree import Text.XML.HXQ.Optimizer import Text.XML.HXQ.Functions-import Text.XML.HXQ.OptionalDB import Language.Haskell.TH+#if __GLASGOW_HASKELL__ >= 609+import Language.Haskell.TH.Quote+#endif undef1 = [| error "Undefined XQuery context (.)" |]@@ -573,6 +578,14 @@ -- | Run an XQuery that reads XML documents and queries databases.--- When evaluated, it returns @(IConnection conn) => conn -> IO XSeq@.+-- When evaluated, it returns @Connection -> IO XSeq@. xqdb :: String -> Q Exp xqdb query = lamE [varP (mkName "_db")] (compileQueryM (parse (scan query)))+++-- | Quasi-quotation for HXQ using xq+#if __GLASGOW_HASKELL__ >= 609+qx = QuasiQuoter xq (\_ -> error "XQuery patterns are not allowed")+#else+qx = error "Quasi-quotation not permitted in earlier ghc versions"+#endif
src/Text/XML/HXQ/Functions.hs view
@@ -13,18 +13,18 @@ - --------------------------------------------------------------------------------------} - {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE BangPatterns #-} module Text.XML.HXQ.Functions where +import HXML(AttList) import Data.List(foldl') import Char(isDigit)-import HXML(AttList) import Text.XML.HXQ.XTree import Language.Haskell.TH+import Debug.Trace {--------------- XPath Steps ---------------------------------------------------------}@@ -38,7 +38,7 @@ _ -> [x] --- XPath step /tag or /*+-- XPath step /tag or / * child_step :: Tag -> XTree -> XSeq child_step tag x = case x of@@ -49,7 +49,7 @@ _ -> [] --- XPath step //tag or //*+-- XPath step //tag or // * descendant_or_self_step :: Tag -> XTree -> XSeq descendant_or_self_step tag (x@(XElem t _ _ _ cs)) | tag==t || tag=="*"@@ -198,8 +198,21 @@ -- XPath steps to be used by the interpreter--- when evaluated, it gives [(String,Tag->XTree->XSeq)]-pFunctions = foldr (\(pname,p) r -> let pn = litE (StringL pname) in [| ($pn,$p) : $r |]) [| [] |] paths+pathFunctions :: [(String,Tag->XTree->XSeq)]+pathFunctions+ = [ ( "child", child_step ),+ ( "descendant", descendant_step ),+ ( "attribute", attribute_step ),+ ( "self", self_step ),+ ( "descendant-or-self", descendant_or_self_step ),+ ( "attribute-descendant", attribute_descendant_step ),+ ( "following-sibling", following_sibling_step ),+ ( "following", following_step ),+ ( "parent", parent_step ),+ ( "ancestor", ancestor_step ),+ ( "preceding-sibling", preceding_sibling_step ),+ ( "preceding", preceding_step ),+ ( "ancestor-or-self", ancestor_or_self_step ) ] {------------ Functions --------------------------------------------------------------}@@ -222,9 +235,15 @@ -- like foldr but with an index foldir :: (a -> Int -> b -> b) -> b -> [a] -> Int -> b foldir c n [] i = n-foldir c n (x:xs) i = c x i (foldir c n xs (i+1))+foldir c n (x:xs) i = c x i (foldir c n xs $! (i+1)) +-- strict: like foldl' but with an index+foldil :: (a -> Int -> b -> b) -> b -> [a] -> Int -> b+foldil c n [] i = n+foldil c n (x:xs) i = (foldil c $! (c x i n)) xs $! (i+1)++ trueXT = XBool True falseXT = XBool False @@ -370,6 +389,7 @@ type Function = [Q Exp] -> Q Exp + -- System functions: they can also be defined as Haskell functions of type (XSeq,...,XSeq) -> XSeq -- but here we make sure they are unfolded and fused with the rest of the query functions :: [(Tag,Int,Function)]@@ -428,16 +448,12 @@ ( "union", 2, \[xs,ys] -> [| distinct ($xs ++ $ys) |] ), ( "intersect", 2, \[xs,ys] -> [| filter (\x -> elem x $ys) $xs |] ), ( "except", 2, \[xs,ys] -> [| filter (\x -> not (elem x $ys)) $xs |] ),- ( "reverse", 1, \[xs] -> [| reverse $xs |] )+ ( "reverse", 1, \[xs] -> [| reverse $xs |] ),+ ( "trace", 2, \[xs,ys] -> [| trace ("***trace:"++show $xs) $ys |] ) ] -system_functions :: [String]-system_functions = map (\(nm,_,_) -> nm) functions ++ map (\(nm,_,_) -> "fn:"++nm) functions----- functions to be used by the interpreter--- when evaluated, it gives [(String,Int,[XSeq]->XSeq)]+-- Functions to be used by the interpreter. When evaluated, it gives [(String,Int,[XSeq]->XSeq)] iFunctions :: Q Exp iFunctions = foldr (\(fname,len,f) r -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]@@ -446,6 +462,86 @@ in [| $entry : $r |]) [| [] |] functions +-- System functions used by the interpreter. They can be derived from functions using the splicing $(iFunctions),+-- but haddock crashes during splicing.+systemFunctions :: [(String,Int,[XSeq]->XSeq)]+systemFunctions+ = [ ( "=", 2, \[xs,ys] -> [ trueXT | x <- text xs, y <- text ys, compareXTrees x y == EQ ] ),+ ( "!=", 2, \[xs,ys] -> if null [ trueXT | x <- text xs, y <- text ys, compareXTrees x y == EQ ]+ then [trueXT]+ else [falseXT] ),+ ( ">", 2, \[xs,ys] -> [ trueXT | x <- text xs, y <- text ys, compareXTrees x y == GT ] ),+ ( "<", 2, \[xs,ys] -> [ trueXT | x <- text xs, y <- text ys, compareXTrees x y == LT ] ),+ ( ">=", 2, \[xs,ys] -> [ trueXT | x <- text xs, y <- text ys, compareXTrees x y `elem` [GT,EQ] ] ),+ ( "<=", 2, \[xs,ys] -> [ trueXT | x <- text xs, y <- text ys, compareXTrees x y `elem` [LT,EQ] ] ),+ ( "eq", 2, \[xs,ys] -> if strictCompare xs ys == EQ then [trueXT] else [falseXT] ),+ ( "neq", 2, \[xs,ys] -> if strictCompare xs ys /= EQ then [trueXT] else [falseXT] ),+ ( "lt", 2, \[xs,ys] -> if strictCompare xs ys == LT then [trueXT] else [falseXT] ),+ ( "gt", 2, \[xs,ys] -> if strictCompare xs ys == GT then [trueXT] else [falseXT] ),+ ( "le", 2, \[xs,ys] -> if strictCompare xs ys `elem` [LT,EQ] then [trueXT] else [falseXT] ),+ ( "ge", 2, \[xs,ys] -> if strictCompare xs ys `elem` [GT,EQ] then [trueXT] else [falseXT] ),+ ( "<<", 2, \[xs,ys] -> [ trueXT | XElem _ _ ox _ _ <- xs, XElem _ _ oy _ _ <- ys, ox < oy ] ),+ ( ">>", 2, \[xs,ys] -> [ trueXT | XElem _ _ ox _ _ <- xs, XElem _ _ oy _ _ <- ys, ox > oy ] ),+ ( "is", 2, \[xs,ys] -> [ trueXT | XElem _ _ ox _ _ <- xs, XElem _ _ oy _ _ <- ys, ox == oy ] ),+ ( "+", 2, \[xs,ys] -> [ arithmetic (+) x y | x <- toNum xs, y <- toNum ys ] ),+ ( "-", 2, \[xs,ys] -> [ arithmetic (-) x y | x <- toNum xs, y <- toNum ys ] ),+ ( "*", 2, \[xs,ys] -> [ arithmetic (*) x y | x <- toNum xs, y <- toNum ys ] ),+ ( "div", 2, \[xs,ys] -> [ arithmetic (/) x y | x <- toNum xs, y <- toNum ys ] ),+ ( "idiv", 2, \[xs,ys] -> [ XInt (div x y) | (XInt x) <- toNum xs, (XInt y) <- toNum ys ] ),+ ( "mod", 2, \[xs,ys] -> [ XInt (mod x y) | (XInt x) <- toNum xs, (XInt y) <- toNum ys ] ),+ ( "uplus", 1, \[xs] -> [ x | x <- toNum xs ] ),+ ( "uminus", 1, \[xs] -> [ case x of XInt n -> XInt (-n); XFloat n -> XFloat (-n) | x <- toNum xs ] ),+ ( "and", 2, \[xs,ys] -> if (conditionTest xs) && (conditionTest ys) then [trueXT] else [falseXT] ),+ ( "or", 2, \[xs,ys] -> if (conditionTest xs) || (conditionTest ys) then [trueXT] else [falseXT] ),+ ( "not", 1, \[xs] -> if conditionTest xs then [falseXT] else [trueXT] ),+ ( "some", 1, \[xs] -> if conditionTest xs then [trueXT] else [falseXT] ),+ ( "count", 1, \[xs] -> [ XInt (length xs) ] ),+ ( "sum", 1, \[xs] -> [ XFloat (sum [ toFloat x | x <- toNum xs ]) ] ),+ ( "avg", 1, \[xs] -> [ XFloat (mean [ toFloat x | x <- toNum xs ]) ] ),+ ( "min", 1, \[xs] -> [ XFloat (minimum [ toFloat x | x <- toNum xs ]) ] ),+ ( "max", 1, \[xs] -> [ XFloat (maximum [ toFloat x | x <- toNum xs ]) ] ),+ ( "to", 2, \[xs,ys] -> [ XInt i | XInt n <- toNum xs, XInt m <- toNum ys, i <- [n..m] ] ),+ ( "text", 1, \[xs] -> text xs ),+ ( "string", 1, \[xs] -> string xs ),+ ( "data", 1, \[xs] -> text xs ),+ ( "node", 1, \[xs] -> [ w | w@(XElem _ _ _ _ _) <- xs ] ),+ ( "exists", 1, \[xs] -> [ XBool (not (null xs)) ] ),+ ( "empty", 0, \[] -> [] ),+ ( "true", 0, \[] -> [trueXT] ),+ ( "false", 0, \[] -> [] ),+ ( "if", 3, \[cs,ts,es] -> if conditionTest cs then ts else es ),+ ( "element", 2, \[tags,xs] -> [ x | tag <- toString tags, x@(XElem t _ _ _ _) <- xs, (t==tag || tag=="*") ] ),+ ( "attribute", 2, \[tags,xs] -> [ z | tag <- toString tags, x <- xs, z <- attribute_step tag x ] ),+ ( "name", 1, \[xs] -> [ XText tag | XElem tag _ _ _ _ <- xs ] ),+ ( "contains", 2, \[xs,text] -> [ trueXT | x <- toString xs, t <- toString text, contains x t ] ),+ ( "substring", 3, \[xs,n1,n2] -> [ XText (take m2 (drop (m1-1) x)) | x <- toString xs,+ XInt m1 <- toNum n1, XInt m2 <- toNum n2 ] ),+ ( "concatenate", 2, \[xs,ys] -> xs ++ ys ),+ ( "distinct-values", 1, \[xs] -> distinct xs ),+ ( "union", 2, \[xs,ys] -> distinct (xs ++ ys) ),+ ( "intersect", 2, \[xs,ys] -> filter (\x -> elem x ys) xs ),+ ( "except", 2, \[xs,ys] -> filter (\x -> not (elem x ys)) xs ),+ ( "reverse", 1, \[xs] -> reverse xs ),+ ( "trace", 2, \[xs,ys] -> trace ("***trace:"++show xs) ys )+ ]+++system_functions :: [String]+system_functions = map (\(nm,_,_) -> nm) systemFunctions ++ map (\(nm,_,_) -> "fn:"++nm) systemFunctions+++-- true, if it is a function in the IO monad+ioFunction :: String -> Q Bool+ioFunction name+ = do info <- reify (mkName name)+ iotp <- [t| IO XSeq |]+ case info of+ VarI _ (AppT _ tp) _ _+ | tp == iotp+ -> return True+ _ -> return False++ -- make a function call callF :: Tag -> Function callF fname args@@ -453,7 +549,7 @@ (_,len,f):_ -> if (length args) == len then f args else error ("wrong number of arguments in function call: " ++ fname)- _ -> -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq+ _ -> -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> IO XSeq let itp = case args of [] -> [t| () |] [_] -> [t| XSeq |]
src/Text/XML/HXQ/Interpreter.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 03/22/08, last update: 12/06/08+- Creation: 03/22/08, last update: 12/19/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,34 +14,21 @@ --------------------------------------------------------------------------------------} -{-# OPTIONS_GHC -fglasgow-exts #-}-{-# LANGUAGE TemplateHaskell #-}---module Text.XML.HXQ.Interpreter where+module Text.XML.HXQ.Interpreter+ ( xquery, xqueryDB, xfileDB, evalInput, xqueryE ) where +import Text.XML.HXQ.Parser+import Text.XML.HXQ.XTree+import Text.XML.HXQ.OptionalDB import Control.Monad import List(sortBy) import XMLParse(parseDocument)-import System.Console.Readline-import Text.XML.HXQ.Parser-import Text.XML.HXQ.XTree+import Readline import Text.XML.HXQ.Optimizer import Text.XML.HXQ.Functions import Text.XML.HXQ.Compiler-import Text.XML.HXQ.OptionalDB --- system functions (=, concat, etc)-systemFunctions :: [(String,Int,[XSeq]->XSeq)]-systemFunctions = $(iFunctions)----- XPath step functions (child, descendant, etc)-pathFunctions :: [(String,Tag->XTree->XSeq)]-pathFunctions = $(pFunctions)-- -- run-time bindings of FLOWR variables type Environment = [(String,XSeq)] @@ -55,7 +42,6 @@ undefv3 = error "Undefined last()" - -- Each XPath predicate must calculate position() and last() from its input XSeq -- if last() is used, then the evaluation is blocking (need to store the whole input XSeq) applyPredicates :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> XSeq@@ -427,12 +413,6 @@ xquery :: String -> IO XSeq xquery query = do (u,_,_) <- xqueryE query [] [] (error "No database connectivity") False return $! u----- | Read an XQuery from a file and run it using the interpreter.-xfile :: String -> IO XSeq-xfile file = do query <- readFile file- xquery query -- | Evaluate the XQuery with database connectivity using the interpreter.
src/Text/XML/HXQ/XQuery.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 03/22/08, last update: 08/14/08+- Creation: 03/22/08, last update: 08/19/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,6 +14,9 @@ --------------------------------------------------------------------------------------} +{-# OPTIONS -cpp #-}++ -- | HXQ is a fast and space-efficient compiler from XQuery (the standard -- query language for XML) to embedded Haskell code. The translation is -- based on Haskell templates. It also provides an interpreter for@@ -26,20 +29,20 @@ -- * The XQuery Compiler xq, xe, -- * The XQuery Interpreter- xquery, xfile,+ xquery, -- * The XQuery Compiler with Database Connectivity xqdb, -- * The XQuery Interpreter with Database Connectivity- xqueryDB, xfileDB,+ xqueryDB, -- * Shredding and Publishing XML Documents Using a Relational Database genSchema, shred, shredC, printSchema, createIndex, -- * Other Functions- XMLEvent(..), connect, disconnect, commit, rollback, prepareSQL, executeSQL+ XMLEvent(..), connect, disconnect, commit, rollback, prepareSQL, executeSQL, qx ) where import HXML(AttList) import Text.XML.HXQ.XTree-import Text.XML.HXQ.Compiler-import Text.XML.HXQ.Interpreter import Text.XML.HXQ.OptionalDB import XMLParse+import Text.XML.HXQ.Compiler+import Text.XML.HXQ.Interpreter
src/Text/XML/HXQ/XTree.hs view
@@ -17,7 +17,8 @@ {-# OPTIONS_GHC -funbox-strict-fields #-} -module Text.XML.HXQ.XTree where+module Text.XML.HXQ.XTree+ ( Tag, XTree(..), XSeq, materialize, putXSeq, showXS ) where import System.IO import Char(isSpace)@@ -116,7 +117,7 @@ where m ((TextEvent t):xs) i = (XText t,xs,i) m ((EmptyEvent n atts):xs) i = (XElem n atts i noParentError [],xs,i+1) m ((StartEvent n atts):xs) i- = let (el,xs',i') = ml xs (i+1)+ = let (el,xs',i') = ml xs $! (i+1) in (XElem n atts i noParentError el,xs',i') m ((PIEvent n s):xs) i = (XPI n s,xs,i) m ((CommentEvent s):xs) i = (XComment s,xs,i)@@ -142,7 +143,7 @@ m ((TextEvent t):xs) i _ = (XText t,xs,i) m ((EmptyEvent n atts):xs) i p = (XElem n atts i p [],xs,i+1) m ((StartEvent n atts):xs) i p- = let (el,xs',i') = ml xs (i+1) node+ = let (el,xs',i') = (ml xs $! (i+1)) node node = XElem n atts i p el in (node,xs',i') m ((PIEvent n s):xs) i _ = (XPI n s,xs,i)
src/noDB/Text/XML/HXQ/OptionalDB.hs view
@@ -47,15 +47,18 @@ connect filepath = noDBerror -disconnect :: conn -> IO ()+-- | Disconnect from the relational database+disconnect :: Connection -> IO () disconnect db = noDBerror -commit :: conn -> IO ()+-- | commit the updates to the database+commit :: Connection -> IO () commit db = noDBerror -rollback :: conn -> IO ()+-- | rollback the updates from the database+rollback :: Connection -> IO () rollback db = noDBerror
− src/readline/System/Console/Readline.hs
@@ -1,10 +0,0 @@-module System.Console.Readline where--import System.IO--readline prompt = do putStr prompt- hFlush stdout- line <- getLine- return (Just line)--addHistory stmt = return ""
src/withDB/Text/XML/HXQ/DB.hs view
@@ -17,7 +17,9 @@ {-# OPTIONS_GHC -funbox-strict-fields #-} -module Text.XML.HXQ.DB where+module Text.XML.HXQ.DB+ ( publishXmlDoc, executeSQL, prepareSQL, genSchema, shred, shredC,+ printSchema, createIndex, insertDB, deleteDB, replaceDB ) where import System.IO.Unsafe import Char(isSpace,isDigit,toLower)