As Dorthe pointed out, we are on the road for the next two weeks. So, I thought it might be a good idea to put everything together. In the last blog posts, I described
- how to wrap a C / C++ structure
- how to define Ruby classes and functions in C
- construct a interactive REPL
Now in order to construct an alternative to the JavaScript shell “arangosh” for ArangoDB, what is missing is a HTTP client. The JavaScript shell already has a builtin C++ class, so I decided to use the same class for the Ruby version. In principle it would be possible to use curl or other libraries.
The wrapper is straight forward.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
static mrb_value ClientConnection_httpGet (mrb_state* mrb, mrb_value self) { char* url; /* int res; */ size_t l; struct RData* rdata; MRubyClientConnection* connection; /* res = */ mrb_get_args(mrb, "s", &url, &l); if (url == 0) { return self; } // looking at "mruby.h" I assume that is the way to unwrap the pointer rdata = (struct RData*) mrb_object(self); connection = (MRubyClientConnection*) rdata->data; if (connection == NULL) { printf("unknown connection (TODO raise error)\n"); return self; } // check header fields map headerFields; // and execute return ClientConnection->getData(url, headerFields); } static void MR_ArangoConnection_Free (mrb_state* mrb, void* p) { printf("free of ArangoCollection called\n"); } static const struct mrb_data_type MR_ArangoConnection_Type = { "ArangoConnection", MR_ArangoConnection_Free }; static void InitMRClientConnection (MR_state_t* mrs, MRubyClientConnection* connection) { struct RClass *rcl; mrb_state* mrb; mrb = &mrs->_mrb; rcl = mrb_define_class(&mrs->_mrb, "ArangoConnection", mrs->_mrb.object_class); mrb_define_method(&mrs->_mrb, rcl, "get", ClientConnection_httpGet, ARGS_REQ(1)); // create the connection variable mrb_value arango = mrb_obj_value(Data_Wrap_Struct(&mrs->_mrb, rcl, &MR_ArangoConnection_Type, (void*) connection)); mrb_gv_set(mrb, mrb_intern(mrb, "$arango"), arango); } |
The whole source code can be found on github in MRClient/arangoirb.cpp. You can either use
1 |
brew install --HEAD arangodb |
or install everything from scratch.
This defines a class ArangoConnection with a method get and a global variable $arango. This now allows to connection to the ArangoDB server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
fceller@opensuse121:~/ArangoDB> ./arangoirb _ _ __ _ _ __ __ _ _ __ __ _ ___ (_)_ __| |__ / _` | '__/ _` | '_ \ / _` |/ _ \| | '__| '_ \ | (_| | | | (_| | | | | (_| | (_) | | | | |_) | \__,_|_| \__,_|_| |_|\__, |\___/|_|_| |_.__/ |___/ Welcome to arangoirb 0.5.2. Copyright (c) 2012 triAGENS GmbH. Using MRUBY 2012-05-16 (a3a9d136aa4835eb50f4be92fbbce1ad503ec4c7) engine. Copyright (c) 2012 mruby developers. Using READLINE 6.2. Connected to Arango DB 127.0.0.1:8529 Version 0.5.2 arangoirb> $arango # arangoirb> $res = $arango.get "/_api/version" {"server"=>"arango", "version"=>"0.5.2"} arangoirb> $res["version"] "0.5.2" arangoirb> Bye Bye! Auf Wiedersehen! さようなら |
The next steps are to add the other methods, make it a bit more like HTTParty, and write the server related functions. I’m not really sure, who a good Ruby interface should look like. So, if you happen to be at NoSQL Matters an Tuesday/Wednesday or at the EuRuKo on Friday/Saturday, please contact us. I would really like to discuss this matter with some Ruby experts.