Skip to content

Latest commit

 

History

History
278 lines (238 loc) · 7.11 KB

README.md

File metadata and controls

278 lines (238 loc) · 7.11 KB

Tash (ট্যাশ)

Tash (ট্যাশ) is a small Open Source (FreeBSD License) C++ library for ArangoDB Database which includes APIs for HTTP based document access and a query builder for AQL (Arango Query Language).

License pipeline status master Codacy Badge Total alerts Language grade: C/C++

tashgoru


Building

prerequisites

  • C++ compiler
  • CMake
  • boost library
  • nlohmann::json [OPTIONAL] (tash ships with a single file version of nlohmann::json)

compiling

git clone https://gitlab.com/neel.basu/tash.git
mkdir build
cd build
cmake ..
make

Basic Example

#include <iostream>
#include <tash/arango.h>
#include <boost/format.hpp>
#include <boost/beast/http/status.hpp>

int main(){
    tash::shell school("school"); // shell("school", "localhost", 8529, "root", "root")
    if(school.exists() == boost::beast::http::status::not_found){
        school.create();
    }
    tash::vertex students(school, "students");
    if(students.exists() == boost::beast::http::status::not_found){
        students.create();
    }
    nlohmann::json document = {
        {"name", "Hijibijbij"},
        {"fathers_name", "Hijibijbij"},
        {"uncles_name", "Hijibijbij"}
    };
    boost::beast::http::status status = students.add(document);
    if(status == boost::beast::http::status::accepted){
        std::cout << boost::format("document created with key %1%") % document["_key"] << std::endl;
    }else{
        std::cout << "Failed to create document with error " << status << std::endl;
    }
    nlohmann::json hijibijbij = students.by_key(document["_key"].get<std::string>());
    std::cout << "retrieved document " << std::endl;
    std::cout << hijibijbij << std::endl;
    return 0;
}

AQL (Arango Query Language) Builder

Retrieve / Filter / Sort

tash::shell shell("school"); // shell("school", "localhost", 8529, "root", "root")
shell <<  select("s").in("students")  // use select instead of FOR because for is a C++ keyword
        / filter((clause("s.name") == name) && (clause("s.fathers_name") == name)) // using std::string puts quotes around the value
        / sort().asc("s._key")
        / yield("s"); // use yield instead of RETURN because return is a C++ keyword
nlohmann::json result;
shell >> result;
FOR s IN students
    FILTER s.name == "Hijibijbij" AND s.fathers_name == "Hijibijbij"
    SORT s._key ASC 
    RETURN s
  select("s").in("students") 
/ filter((clause("s.name") == "s.fathers_name")) // using C string doesn't put quotes around the value
/ sort().asc("s._key")
/ yield("s"); 
FOR s IN students
    FILTER s.name == s.fathers_name
    SORT s._key ASC 
    RETURN s

insert

insert single row

insert(nlohmann::json{
    {"name", "tash"},
    {"fathers_name", "tash"}
}).in("students");
INSERT {"fathers_name":"tash","name":"tash"} INTO students

insert multiple rows

select("u").in({
    {"name", "tash"},
    {"fathers_name", "tash"}
}) / insert("u").in("students")
FOR u IN {"fathers_name":"tash","name":"tash"}
    INSERT u INTO students

generate rows

  • in nlohmann::json string values are always quoted
  • tash::assign generates non-nested key value pairs (non-nested json)
  • C style strings are unquoted, std::string is quoted
  select("i").in(1, 10) 
/ insert(
    assign("name", "CONCAT('tash', i)")
   .assign("gender", "(i % 2 == 0 ? 'f' : 'm')")
   .assign("fathers_name", std::string("tash"))
  ).in("users")
FOR i IN 1..10
    INSERT {
        name: CONCAT('test', i), 
        gender: (i % 2 == 0 ? 'f' : 'm'),
        fathers_name: "tash"
    } INTO users

update

update(nlohmann::json{
    {"_key", 1234}
}).with({
    {"uncles_name", "tash"}
}).in("students")
UPDATE {"_key":1234} WITH {"uncles_name":"tash"} IN students

let

  (let("date") = "DATE_NOW()")
/ select("user").in("users")
/ filter(clause("user.isImportantUser") == "null")
/ (let("numberOfLogins")  = 
    select("login").in("logins")
    / filter(clause("login.user") == "user._key")
    / collect().with("COUNT").in("numLogins")
    / yield("numLogins")
)
/ filter(clause("numberOfLogins") > 50)
/ update("user").with(
     assign("isImportantUser", 1)
    .assign("dateBecameImportant", "date")
    .assign("uncles_name", std::string("tash"))
).in("users")
LET date = DATE_NOW()
    FOR user IN users
        FILTER user.isImportantUser == null
        LET numberOfLogins = (
            FOR login IN logins
                FILTER login.user == user._key
                COLLECT  WITH COUNT INTO numLogins
                RETURN numLogins
        )
        FILTER numberOfLogins > 50
        UPDATE user WITH {
            isImportantUser: 1, 
            dateBecameImportant: date,
            uncles_name: "tash"
        } IN users

replace

replace(nlohmann::json{
    {"_key", 1234}
}).with({
    {"name", "tash"},
    {"uncles_name", "tash"}
}).in("students")
REPLACE {"_key":1234} 
    WITH {
        "name":"tash",
        "uncles_name":"tash"
    } IN students

remove

erase(assign("_key", "1")).in("students")
REMOVE {_key: 1} IN students

upsert

upsert(nlohmann::json{
    {"name", "tokai"}
}).insert({
    {"name", "tokai"},
    {"fathers_name", "tokai"}
}).update({
    {"name", "tokai"},
    {"fathers_name", "tokai"}
}).in("students")
UPSERT {"name":"tokai"} 
    INSERT {"fathers_name":"tokai","name":"tokai"} 
    UPDATE {"fathers_name":"tokai","name":"tokai"}
    IN students

create graph

auto graph = ddl::graph_definition("corpus")
    .add_edge_definition(ddl::edge_definition("StructuralE").add_from("Word").add_to("Word").add_to("Sentence"))
    .add_edge_definition(ddl::edge_definition("WNeighbourhoodE").add_from("Word").add_to("Word"))
    .add_edge_definition(ddl::edge_definition("InstanceE").add_from("Word").add_to("Vocabulary"));
query("_api/gharial", graph.json().dump());

create aql function

std::string function_str = R"(
    function(p1, p2){
        // function body
    }
)";
auto fnc = nlohmann::json({
    {"name", "NS::FNAME"},
    {"code", function_str},
    {"isDeterministic", true}
});
query("_api/aqlfunction", fnc.dump());