package models;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.util.Date;
import java.util.Random;
import org.brackit.xquery.QueryContext;
import org.brackit.xquery.QueryException;
import org.brackit.xquery.XQuery;
import org.brackit.xquery.compiler.CompileChain;
import org.brackit.xquery.xdm.Sequence;
import org.sirix.access.Databases;
import org.sirix.access.conf.DatabaseConfiguration;
import org.sirix.access.conf.ResourceConfiguration;
import org.sirix.access.conf.SessionConfiguration;
import org.sirix.api.Database;
import org.sirix.api.NodeReadTrx;
import org.sirix.api.NodeWriteTrx;
import org.sirix.api.Session;
import org.sirix.exception.SirixException;
import org.sirix.io.StorageType;
import org.sirix.xquery.SirixCompileChain;
import org.sirix.xquery.node.DBNode;
import org.sirix.xquery.node.DBStore;
/**
* A few examples (some taken from the official brackit examples). Usually you
* would use a logger for all output!
*
* @author Johannes Lichtenberger
* @author Sebastian Bächle
*
*/
public final class XQueryUsage {
/** User home directory. */
private static final String USER_HOME = System.getProperty("user.home");
/** Storage for databases: Sirix data in home directory. */
private static final File LOCATION = new File(USER_HOME, "sirix-data");
/** Severity used to build a random sample document. */
enum Severity {
low, high, critical
};
/**
* Main method.
*
* @param args
* not used
*/
public static void main(final String[] args){
// loadDocumentAndQuery();
// System.out.println();
// loadDocumentAndUpdate();
// System.out.println();
// loadCollectionAndQuery();
// System.out.println();
//loadDocumentAndQueryTemporal();
// datbaseSirix();
}
/**
* Load a document and query it.
*/
private static void loadDocumentAndQuery() throws QueryException,
IOException, SirixException {
final File doc = new File(new StringBuilder("src")
.append(File.separator).append("main").append(File.separator)
.append("resources").append(File.separator).append("test.xml")
.toString());
// Initialize query context and store.
final DBStore store = DBStore.newBuilder().build();
QueryContext ctx = new QueryContext(store);
// Use XQuery to load sample document into store.
System.out.println("Loading document:");
URI docUri = doc.toURI();
String xq1 = String.format("bit:load('mydoc.xml', '%s')",
docUri.toString());
System.out.println(xq1);
new XQuery(xq1).evaluate(ctx);
try (final Database database = Databases.openDatabase(new File(
new StringBuilder(3).append(LOCATION).append(File.separator)
.append("mydoc.xml").toString()))) {
// Reuse store and query loaded document.
final QueryContext ctx2 = new QueryContext(store);
System.out.println();
System.out.println("Query loaded document:");
final String xq2 = "doc('mydoc.xml')/nachrichten/nachricht[betreff/text()='sommer' or betreff/text()='strand' or text/text()='sommer' or text/text()='strand']";
System.out.println(xq2);
XQuery query = new XQuery(new SirixCompileChain(store), xq2);
query.prettyPrint().serialize(ctx2, System.out);
}
System.out.println();
store.close();
}
/**
* Load a document and update it.
*/
private static void loadDocumentAndUpdate() throws QueryException,
IOException {
// Prepare sample document.
final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
final File doc = generateSampleDoc(tmpDir, "sample");
doc.deleteOnExit();
// Initialize query context and store.
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx = new QueryContext(store);
// Use XQuery to load sample document into store.
System.out.println("Loading document:");
URI docUri = doc.toURI();
final String xq1 = String.format(
"sdb:load('mycol.xml', 'mydoc.xml', '%s')",
docUri.toString());
System.out.println(xq1);
new XQuery(xq1).evaluate(ctx);
// Reuse store and query loaded document.
final QueryContext ctx2 = new QueryContext(store);
System.out.println();
System.out.println("Query loaded document:");
final String xq2 = "insert nodes <a><b/></a> into sdb:doc('mydoc.xml')/log";
System.out.println(xq2);
new XQuery(xq2).execute(ctx2);
store.commitAll();
System.out.println();
}
}
/**
* Load a collection and query it.
*/
private static void loadCollectionAndQuery() throws QueryException,
IOException {
// Prepare directory with sample documents.
final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
final File dir = new File(tmpDir + File.separator + "docs"
+ System.currentTimeMillis());
if (!dir.mkdir()) {
throw new IOException("Directory " + dir + " already exists");
}
dir.deleteOnExit();
for (int i = 0; i < 10; i++) {
generateSampleDoc(dir, "sample");
}
// Initialize query context and store.
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx = new QueryContext(store);
// Use XQuery to load all sample documents into store.
System.out.println("Load collection from files:");
final String xq1 = String.format(
"bit:load('mydocs.col', io:ls('%s', '\\.xml$'))", dir);
System.out.println(xq1);
new XQuery(xq1).evaluate(ctx);
// Reuse store and query loaded collection.
final QueryContext ctx2 = new QueryContext(store);
System.out.println();
System.out.println("Query loaded collection:");
final String xq2 = "for $log in collection('mydocs.col')/log\n"
+ "where $log/@severity='critical'\n" + "return\n"
+ "<message>\n" + " <from>{$log/src/text()}</from>\n"
+ " <body>{$log/msg/text()}</body>\n" + "</message>\n";
System.out.println(xq2);
final XQuery q = new XQuery(xq2);
q.prettyPrint();
q.serialize(ctx2, System.out);
System.out.println();
// Use XQuery to load all sample documents once more into store.
System.out.println("Load collection from files:");
final String xq3 = String
.format("bit:load('mydocs.col', io:ls('%s', '\\.xml$'), fn:false())",
dir.toString());
System.out.println(xq3);
new XQuery(xq3).evaluate(ctx);
}
}
/**
* Load a document and query it (temporal enhancements).
*/
public static void loadDocumentAndQueryTemporal() throws QueryException,
IOException, SirixException {
// Prepare sample document.
final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
// Initialize query context and store.
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx = new QueryContext(store);
final CompileChain compileChain = new SirixCompileChain(store);
final File doc1 = generateSampleDoc(tmpDir, "sample1");
doc1.deleteOnExit();
final URI docUri = doc1.toURI();
// Use XQuery to load sample document into store.
System.out.println("Loading document:");
final String xq1 = String.format(
"sdb:load('mydocs.col', 'resource1', '%s')",
docUri.toString());
System.out.println(xq1);
new XQuery(compileChain, xq1).evaluate(ctx);
// Reuse store and insert into loaded document with a subsequent
// explicit commit.
final QueryContext ctx2 = new QueryContext(store);
System.out.println();
System.out.println("Insert into loaded document:");
final String xq2 = "insert nodes <a><b/>test<c/>55<d>22</d></a> into sdb:doc('mydocs.col', 'resource1', (), fn:boolean(1))/log";
System.out.println(xq2);
final XQuery q1 = new XQuery(compileChain, xq2);
q1.execute(ctx2);
System.out.println("Commit changes:");
final String xq3 = "sdb:commit(sdb:doc('mydocs.col', 'resource1', (), fn:boolean(1)))";
final XQuery q2 = new XQuery(compileChain, xq3);
q2.execute(ctx2);
System.out.println();
}
// Create and commit CAS indexes on all attribute- and text-nodes.
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx3 = new QueryContext(store);
System.out.println();
System.out
.println("Create a cas index for all attributes and another one for text-nodes. A third one is created for all integers:");
final XQuery q = new XQuery(
new SirixCompileChain(store),
"let $doc := sdb:doc('mydocs.col', 'resource1', (), fn:boolean(1)) "
+ "let $casStats1 := sdb:create-cas-index($doc, 'xs:string', '//@*') "
+ "let $casStats2 := sdb:create-cas-index($doc, 'xs:string', '//*') "
+ "let $casStats3 := sdb:create-cas-index($doc, 'xs:integer', '//*') "
+ "return <rev>{sdb:commit($doc)}</rev>");
q.serialize(ctx3, System.out);
System.out.println();
System.out.println("CAS index creation done.");
}
// Create and commit path index on all elements.
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx3 = new QueryContext(store);
System.out.println();
System.out
.println("Create path index for all elements (all paths):");
final XQuery q = new XQuery(
new SirixCompileChain(store),
"let $doc := sdb:doc('mydocs.col', 'resource1', (), fn:boolean(1)) "
+ "let $stats := sdb:create-path-index($doc, '//*') "
+ "return <rev>{sdb:commit($doc)}</rev>");
q.serialize(ctx3, System.out);
System.out.println();
System.out.println("Path index creation done.");
}
// Create and commit name index on all elements with QName 'src' or
// 'msg'.
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx3 = new QueryContext(store);
System.out.println();
System.out
.println("Create name index for all elements with name 'src' or 'msg':");
final XQuery q = new XQuery(
new SirixCompileChain(store),
"let $doc := sdb:doc('mydocs.col', 'resource1', (), fn:boolean(1)) "
+ "let $stats := sdb:create-name-index($doc, fn:QName((), 'src')) "
+ "return <rev>{sdb:commit($doc)}</rev>");
q.serialize(ctx3, System.out);
System.out.println();
System.out.println("Name index creation done.");
}
// Query CAS index.
try (final DBStore store = DBStore.newBuilder().build()) {
System.out.println("");
System.out.println("Find CAS index for all attribute values.");
final QueryContext ctx3 = new QueryContext(store);
final String query = "let $doc := sdb:doc('mydocs.col', 'resource1') return sdb:scan-cas-index($doc, sdb:find-cas-index($doc, 'xs:string', '//@*'), 'bar', true(), 0, ())";
final Sequence seq = new XQuery(new SirixCompileChain(store), query)
.execute(ctx3);
// final Iter iter = seq.iterate();
// for (Item item = iter.next(); item != null; item = iter.next()) {
// System.out.println(item);
// }
/*
* final Comparator<Tuple> comparator = new Comparator<Tuple>() {
*
* @Override public int compare(Tuple o1, Tuple o2) { return
* ((Node<?>) o1).cmp((Node<?>) o2); } }; final Sequence sortedSeq =
* new SortedNodeSequence(comparator, seq, true); final Iter
* sortedIter = sortedSeq.iterate();
*
* System.out.println("Sorted index entries in document order: ");
* for (Item item = sortedIter.next(); item != null; item =
* sortedIter .next()) { System.out.println(item); }
*/
}
// Query CAS index.
try (final DBStore store = DBStore.newBuilder().build()) {
System.out.println("");
System.out
.println("Find CAS index for all text values which are integers between 10 and 100.");
final QueryContext ctx3 = new QueryContext(store);
final String query = "let $doc := sdb:doc('mydocs.col', 'resource1') return sdb:scan-cas-index-range($doc, sdb:find-cas-index($doc, 'xs:integer', '//*'), 10, 100, true(), true(), ())";
final Sequence seq = new XQuery(new SirixCompileChain(store), query)
.execute(ctx3);
// final Iter iter = seq.iterate();
// for (Item item = iter.next(); item != null; item = iter.next()) {
// System.out.println(item);
// }
/*
* final Comparator<Tuple> comparator = new Comparator<Tuple>() {
*
* @Override public int compare(Tuple o1, Tuple o2) { return
* ((Node<?>) o1).cmp((Node<?>) o2); } }; final Sequence sortedSeq =
* new SortedNodeSequence(comparator, seq, true); final Iter
* sortedIter = sortedSeq.iterate();
*
* System.out.println("Sorted index entries in document order: ");
* for (Item item = sortedIter.next(); item != null; item =
* sortedIter .next()) { System.out.println(item); }
*/
}
// Query path index which are children of the log-element (only
// elements).
try (final DBStore store = DBStore.newBuilder().build()) {
System.out.println("");
System.out
.println("Find path index for all elements which are children of the log-element (only elements).");
final QueryContext ctx3 = new QueryContext(store);
final DBNode node = (DBNode) new XQuery(
new SirixCompileChain(store), "doc('mydocs.col')")
.execute(ctx3);
/* final Optional<IndexDef> index = node.getTrx().getSession()
.getRtxIndexController(node.getTrx().getRevisionNumber())
.getIndexes().findPathIndex(Path.parse("//log/*"));
System.out.println(index);
// last param '()' queries whole index.
final String query = "let $doc := sdb:doc('mydocs.col', 'resource1') "
+ "return sdb:scan-path-index($doc, "
+ index.get().getID()
+ ", '//log/*')";
final Sequence seq = new XQuery(new SirixCompileChain(store), query)
.execute(ctx3);
/*
* final Comparator<Tuple> comparator = new Comparator<Tuple>() {
*
* @Override public int compare(Tuple o1, Tuple o2) { return
* ((Node<?>) o1).cmp((Node<?>) o2); } }; final Sequence sortedSeq =
* new SortedNodeSequence(comparator, seq, true); final Iter
* sortedIter = sortedSeq.iterate();
*
* System.out.println("Sorted index entries in document order: ");
* for (Item item = sortedIter.next(); item != null; item =
* sortedIter .next()) { System.out.println(item); }
*/
}
// Query name index.
try (final DBStore store = DBStore.newBuilder().build()) {
System.out.println("");
System.out.println("Query name index (src-element).");
final QueryContext ctx3 = new QueryContext(store);
final String query = "let $doc := sdb:doc('mydocs.col', 'resource1')"
+ " let $sequence := sdb:scan-name-index($doc, sdb:find-name-index($doc, fn:QName((), 'src')), fn:QName((), 'src'))"
+ " return sdb:sort($sequence)";
final XQuery q = new XQuery(new SirixCompileChain(store), query);
q.prettyPrint();
q.serialize(ctx3, System.out);
}
try (final DBStore store = DBStore.newBuilder().build()) {
final QueryContext ctx = new QueryContext(store);
System.out.println();
System.out.println("Query loaded document:");
final String xq3 = "doc('mydocs.col')/log/all-time::*";
System.out.println(xq3);
XQuery q = new XQuery(new SirixCompileChain(store), xq3);
q.prettyPrint();
q.serialize(ctx, System.out);
// Serialize first version to XML
// ($user.home$/sirix-data/output-revision-1.xml).
final QueryContext ctx4 = new QueryContext(store);
final String xq4 = "bit:serialize(doc('mydocs.col', 1))";
q = new XQuery(xq4);
try (final PrintStream out = new PrintStream(new FileOutputStream(
new File(new StringBuilder(LOCATION.getAbsolutePath())
.append(File.separator)
.append("output-revision-1.xml").toString())))) {
q.prettyPrint().serialize(ctx4, out);
}
System.out.println();
// Serialize second version to XML
// ($user.home$/sirix-data/output-revision-1.xml).
final QueryContext ctx5 = new QueryContext(store);
final String xq5 = "bit:serialize(doc('mydocs.col', 2))";
q = new XQuery(xq5);
try (final PrintStream out = new PrintStream(new FileOutputStream(
new File(new StringBuilder(LOCATION.getAbsolutePath())
.append(File.separator).append(File.separator)
.append("output-revision-2.xml").toString())))) {
q.prettyPrint().serialize(ctx5, out);
}
System.out.println();
}
try (final DBStore store = DBStore.newBuilder().build()) {
final File doc = new File(new StringBuilder("src")
.append(File.separator).append("main")
.append(File.separator).append("resources")
.append(File.separator).append("test.xml").toString());
final QueryContext ctx = new QueryContext(store);
System.out.println();
URI docUri = doc.toURI();
final String xq3 = String.format(
"sdb:load('mycoll.col', 'mydoc.xml', '%s')",
docUri.toString());
System.out.println(xq3);
final XQuery q = new XQuery(new SirixCompileChain(store), xq3);
q.execute(ctx);
}
}
/**
* Generate a small sample document.
*
* @param dir
* the directory
* @param prefix
* prefix of name to use
* @return the generated file
* @throws IOException
* if any I/O exception occured
*/
private static File generateSampleDoc(final File dir, final String prefix)
throws IOException {
final File file = File.createTempFile(prefix, ".xml", dir);
file.deleteOnExit();
final PrintStream out = new PrintStream(new FileOutputStream(file));
final Random rnd = new Random();
final long now = System.currentTimeMillis();
final int diff = rnd.nextInt(6000 * 60 * 24 * 7);
final Date tst = new Date(now - diff);
final Severity sev = Severity.values()[rnd.nextInt(3)];
final String src = "192.168." + (1 + rnd.nextInt(254)) + "."
+ (1 + rnd.nextInt(254));
final int mlen = 10 + rnd.nextInt(70);
final byte[] bytes = new byte[mlen];
int i = 0;
while (i < mlen) {
int wlen = 1 + rnd.nextInt(8);
int j = i;
while (j < Math.min(i + wlen, mlen)) {
bytes[j++] = (byte) ('a' + rnd.nextInt('z' - 'a' + 1));
}
i = j;
if (i < mlen - 1) {
bytes[i++] = ' ';
}
}
final String msg = new String(bytes);
out.print("<?xml version='1.0'?>");
out.print(String.format("<log tstamp='%s' severity='%s' foo='bar'>",
tst, sev));
out.print(String.format("<src>%s</src>", src));
out.print(String.format("<msg>%s</msg>", msg));
out.print("oops1");
out.print("<b/>");
out.print("oops2");
out.print("</log>");
out.close();
return file;
}
}