In the relational world, PL/SQL is used to store business/application logic inside the relational database. The same movement is currently happening in the NoSQL. Redis for example uses LUA script in its newest version (2.6), to allow developers to tweak Redis. There a lot of use-cases for a programming language in document-stores. Programming languages are used in various document stores like ArangoDB, CouchDB, MongoDB, or VoltDB. In my opinion in the following use-cases a suitable language like Ruby will be most handy.

Transactions: Quite a lot NoSQL databases, that implement transaction, use scripts to do so. While transaction in a RDBMS were long running processes, transactions in NoSQL database are short-running computations or modification. For example, Redis requires a complicated optimistic locking to simulate transactions. The same effect can much easier achieved with small script.

Business Logic: Document stores and also most graph databases store objects aka documents as JSON objects. One of the anti-patterns is to store an age field in these objects. It is very easy to compute the age from the birthday in the client. But even with such a simple example. there  are pit-falls. What is the correct time-zone? How to handle a “is 18-year check” if the birthday is the 29.Feb? Instead of handling these corner-cases in each different client, it is much easier to implement them once and for all in the server.

Permission: With complex queries, permission handling can be a performance disaster. One easy solution is to wrap the query in the a script and handle permission there.

Graph Traversal: In order to implement complex graph queries, one either needs ascii arts or scripts to describe the traversal.

Different databases implement these use-cases using different languages like Lua, Erlang, or JavaScript. With this blog I would like to promote Ruby as a possible candidate for such tasks.

Using MRuby within ArangoDB

ArangoDB, like CouchDB, has a HTTP interface and uses JSON for document exchange. The internal Http-Server of ArangoDB uses data structures for request and responses that loosely resambles the WEBrick interface of Ruby.

I tried to implement the age example with ArangoDB using MRuby. The first step is to define the HttpResponse and HttpRequest – as @tisba pointed out, it will be much more Ruby-like when using attribute_reader, see here. I will rewrite this as soon as this issue with MRuby has been solved.

and

The AbstractServlet is also straight forward.

The missing piece is the C++/Ruby bridge. This bridge takes a C++ request objects, converts it into a Ruby object, calls the service method, takes the response object and converts it back to C++. The complete source code can be found at https://github.com/triAGENS/ArangoDB/tree/devel/arangod/MRServer.

Hallo World

The first script to try is always the “hallo world”:

Arango::HttpServer.mount “/_ruby/version”, VersionHandler

Using curl we now get:

Age Example

The age example is almost as simple – no error handling :-). Assume that the collection containing the users is called “users” and the birthday is in attribute of the same name. The call to get the user with id 123456 is “/_ruby/user/123456”.