[Xapian-discuss] Node.js binding
Liam
xapian at networkimprov.net
Mon Oct 17 21:54:06 BST 2011
On Mon, Oct 17, 2011 at 10:11 AM, Dan Colish <dcolish at gmail.com> wrote:
> On Mon, Oct 17, 2011 at 9:52 AM, Liam <xapian at networkimprov.net> wrote:
>
> ...
>
> > Perhaps we can define a subset of the API to implement initially in a
> > binding. What are the essential routines to issue a query and retrieve
> > results, and how are they typically used?
> > _______________________________________________
> > Xapian-discuss mailing list
> > Xapian-discuss at lists.xapian.org
> > http://lists.xapian.org/mailman/listinfo/xapian-discuss
> >
>
>
> Hi Liam,
>
> Take a look at our quickstart <http://xapian.org/docs/quickstart.html> for
> the bare minimum of what is required to perform a search. Also, you might
> find the smoketests for the various language bindings helpful. I have a
> little interest in seeing Node bindings get built due to my curiosity for
> the language implementation. If I have some time over the weekend, I'll try
> out a spike. In the meantime feel free to share anything you've written.
>
> --Dan
>
OK, based on the quickstart page, here's a sketch for the query API on the
Javascript side. We should expand this to all features necessary for basic
use before coding. Where I assume disk I/O can happen, you see
"function(err, x) { " which pushes subsequent work into a callback. I've
marked other spots where I assumed no I/O, but wasn't sure.
var xapian = require('xapian'); // load & init the module
xapian.newDatabase('db1', function(err, databases) {
if (err) throw err;
xapian.newDatabase('db2', function(err, db2) {
if (err) throw err;
databases.add_database(db2);
var enquire = new xapian.Enquire(databases); // assumes no i/o
var query = new xapian.Query(xapian.Query.OP_OR, ['term1', 'term2']);
console.log("Performing query [" + query.get_description() + "]");
enquire.set_query(query); // assumes no i/o
enquire.get_mset(0, 10, function(err, mset) { // mset is an array-like
object
if (err) throw err
console.log(mset.length + " results found");
iter(0);
function iter(i) { // can't for-loop when depending on callback
if (i === mset.length)
return;
var doc = new xapian.Document(mset[i].document); // .id?
doc.get_data(function(err, data) {
if (err) throw err;
console.log("Document ID " + mset[i].id + "\t" + mset[i].percent +
"% [" + data + "]");
iter(++i);
});
}
});
});
});
On the C++ side, this SQLite binding is instructive:
https://github.com/developmentseed/node-sqlite3/tree/master/src
See also the how-to:
https://github.com/kkaefer/node-cpp-modules
The pattern for an I/O module is to define a class -- with static member
functions and normal member variables -- for each API class. API methods
which perform I/O require a trio of static functions:
class Database : public EventEmitter {
public:
static void Init(Handle<Object> target); // setup the module
protected:
// setup a new instance for user
static Handle<Value> New(const Arguments& args);
// trio of methods for I/O
static Handle<Value> AddDb(const Arguments& args); // verify & extract
args into a request, queue the request
static int AddDb_pool(eio_req *req); // function runs in the thread pool
static int AddDb_done(eio_req *req); // create V8 result object, call
user callback
// single method for non-I/O
static Handle<Value> GetSomething(const Arguments& args); // return a V8
value
protected:
// object data
};
More information about the Xapian-discuss
mailing list