[Xapian-discuss] Node.js binding

Liam xapian at networkimprov.net
Wed Oct 19 18:09:41 BST 2011


On Mon, Oct 17, 2011 at 1:54 PM, Liam <xapian at networkimprov.net> wrote:

> 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
> };
>

I've started an initial pass on this binding, to implement just the above.
However I need some guidance on which methods do I/O and therefore block.


More information about the Xapian-discuss mailing list