Skip to content
This repository has been archived by the owner on May 4, 2023. It is now read-only.

Commit

Permalink
Merge branch 'rhino' into beta
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Newson committed Mar 6, 2009
2 parents 70a1e09 + 81aaeb1 commit 5ed0868
Show file tree
Hide file tree
Showing 8 changed files with 607 additions and 6 deletions.
10 changes: 7 additions & 3 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@

* better lifecycle management (couchdb keeps killing our java process when it thinks a query is too slow, this prevents ever building a decent FieldCache for sorting, etc).
* use javascript to let couchdb user to program output transformation rather than current blanket strategy
* indexer as updater process
* searcher as external
* sort cache can take too long to build, respond with keep-alive messages.
* revisit numeric handling (it's too surprising)
* document rhino integration
* code tidy in general.
* add a _status uri that lets you see index state/progress.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
<artifactId>tika</artifactId>
<version>0.2</version>
</dependency>
<dependency>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
<version>1.7R1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/org/apache/couchdb/lucene/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ public JSONObject getAllDocsBySeq(final String dbname, final long from, final in
}

public JSONObject getDoc(final String dbname, final String id, final String rev) throws HttpException, IOException {
return JSONObject.fromObject(get(String.format("%s/%s?rev=%s", dbname, id, rev)));
if (rev == null)
return JSONObject.fromObject(get(String.format("%s/%s", dbname, id)));
else
return JSONObject.fromObject(get(String.format("%s/%s?rev=%s", dbname, id, rev)));
}

public JSONObject getDocs(final String dbname, final String... ids) throws HttpException, IOException {
Expand Down Expand Up @@ -96,7 +99,7 @@ private String post(final String path, final String body) throws HttpException,

private synchronized String execute(final HttpMethodBase method) throws HttpException, IOException {
try {
CLIENT.executeMethod(method);
CLIENT.executeMethod(method);
final InputStream in = method.getResponseBodyAsStream();
try {
final StringWriter writer = new StringWriter(2048);
Expand Down
21 changes: 20 additions & 1 deletion src/main/java/org/apache/couchdb/lucene/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ private void openReader() throws IOException {

private class IndexUpdateTask extends TimerTask {

private Rhino filter = null;

@Override
public void run() {
IndexWriter writer = null;
Expand All @@ -87,6 +89,18 @@ public void run() {
final String[] dbnames = db.getAllDatabases();
writer = newWriter();
for (final String dbname : dbnames) {
// Database might supply a filter.
final JSONObject designDoc = db.getDoc(dbname, "_design/lucene", null);
if (designDoc.containsKey("filter")) {
String filterFun = designDoc.getString("filter");
// Strip start and end double quotes.
filterFun = filterFun.replaceAll("^\"*", "");
filterFun = filterFun.replaceAll("\"*$", "");
filter = new Rhino(filterFun);
} else {
filter = null;
}

commit |= updateDatabase(writer, dbname);
}
} catch (final IOException e) {
Expand Down Expand Up @@ -167,13 +181,18 @@ private boolean updateDatabase(final IndexWriter writer, final String dbname) th
private void updateDocument(final IndexWriter writer, final String dbname, final JSONObject obj)
throws IOException {
final Document doc = new Document();
final JSONObject json = obj.getJSONObject("doc");
JSONObject json = obj.getJSONObject("doc");

// Skip design documents.
if (json.getString(Config.ID).startsWith("_design")) {
return;
}

// Filter, if supplied.
if (filter != null) {
json = JSONObject.fromObject(filter.parse(json.toString()));
}

// Standard properties.
doc.add(token(Config.DB, dbname, false));
final String id = (String) json.remove(Config.ID);
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/org/apache/couchdb/lucene/Rhino.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.apache.couchdb.lucene;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;

public final class Rhino {

private final ContextFactory contextFactory = new ContextFactory();

private final Context context;

private final Scriptable scope;

private final Function userFun;

private final Function systemFun;

private final String fun;

public Rhino(final String fun) throws IOException {
this.fun = fun;
this.context = contextFactory.enterContext();
context.setOptimizationLevel(9);
scope = context.initStandardObjects();

// compile user-defined function.
this.userFun = context.compileFunction(scope, fun, "userFun", 0, null);

// compile system function.
this.systemFun = context.compileFunction(scope,
"function(json,filter) { var doc=JSON.parse(json); doc=filter(doc); return JSON.stringify(doc); }",
"systemFun", 0, null);

// add JSON parser.
context.evaluateString(scope, loadJSONParser(), "json2", 0, null);
}

private String loadJSONParser() throws IOException {
final InputStream in = Rhino.class.getClassLoader().getResourceAsStream("json2.js");
try {
return IOUtils.toString(in, "UTF-8");
} finally {
in.close();
}
}

public String parse(final String doc) {
return (String) systemFun.call(context, scope, null, new Object[] { doc, userFun });
}

public void close() {
Context.exit();
}

public String toString() {
return fun;
}

}
Loading

0 comments on commit 5ed0868

Please sign in to comment.