Skip to content
This repository has been archived by the owner on Jun 18, 2020. It is now read-only.

Commit

Permalink
Merge pull request #31 from sandrokeil/feature/async
Browse files Browse the repository at this point in the history
Added more functionality to Connection class
  • Loading branch information
sandrokeil authored Nov 18, 2017
2 parents 7dde401 + 48c5d27 commit e20caf1
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 48 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ add_library(arangodb SHARED
src/connection.cpp
src/main.cpp
src/request.cpp
src/response.cpp
src/vpack.cpp
)

Expand Down
137 changes: 130 additions & 7 deletions src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ namespace arangodb { namespace fuerte { namespace php {
{"vst_version", ConnectionOptions::VST_VERSION}
};

Connection::Connection(): threadCount(std::thread::hardware_concurrency())
Connection::Connection():
threadCount(std::thread::hardware_concurrency()),
asyncWaitGroup(new fu::WaitGroup())
{
if(this->threadCount < 1) {
this->threadCount = 1;
}
}

Connection::~Connection()
{
delete this->asyncWaitGroup;
}

void Connection::__construct(Php::Parameters &params)
{
this->options = params[0];
Expand Down Expand Up @@ -84,13 +91,8 @@ namespace arangodb { namespace fuerte { namespace php {
}


Php::Value Connection::send(Php::Parameters &params)
Response* Connection::sendRequest(Request* request)
{
if(!params[0].instanceOf("ArangoDb\\Request"))
throw Php::Exception("Expected request to be of type Request");

Request* request = (Request*)params[0].implementation();

fu::WaitGroup wg;
wg.add();

Expand All @@ -110,7 +112,128 @@ namespace arangodb { namespace fuerte { namespace php {
throw Php::Exception("Sending request to ArangoDB failed");
}

return response;
}

void Connection::sendRequestAsync(Request* request, Php::Value& callback)
{
this->asyncWaitGroup->add();

this->connection->sendRequest(
std::move(request->getFuerteRequest()),
[=](fu::Error, std::unique_ptr<fu::Request>, std::unique_ptr<fu::Response> res){
callback(Php::Object("ArangoDb\\Response", new Response(*res)));

this->asyncWaitGroup->done();
}
);
}


Php::Value Connection::send(Php::Parameters &params)
{
if(!params[0].instanceOf("ArangoDb\\Request"))
throw Php::Exception("Expected request to be of type Request");

Request* request = (Request*)params[0].implementation();

Response* response = this->sendRequest(request);
return Php::Object("ArangoDb\\Response", response);
}

void Connection::sendAsync(Php::Parameters &params)
{
if(!params[0].instanceOf("ArangoDb\\Request"))
throw Php::Exception("Expected request to be of type Request");

if(!params[1].isCallable())
throw Php::Exception("Expected callback to be of type Callable");

Request* request = (Request*)params[0].implementation();
this->sendRequestAsync(request, params[1]);
}


Php::Value Connection::methodDelete(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_DELETE);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

Php::Value Connection::methodGet(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_GET);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

Php::Value Connection::methodPost(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_POST);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

Php::Value Connection::methodPut(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_PUT);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

Php::Value Connection::methodHead(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_HEAD);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

Php::Value Connection::methodPatch(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_PATCH);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

Php::Value Connection::methodOptions(Php::Parameters &params)
{
if(!params[1].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

Request request(params[0].stringValue(), (Vpack*)params[1].implementation());
request.setHttpMethod(Request::METHOD_OPTIONS);
return Php::Object("ArangoDb\\Response", this->sendRequest(&request));
}

void Connection::wait()
{
auto success = this->asyncWaitGroup->wait_for(std::chrono::seconds(this->defaultTimeout));

delete this->asyncWaitGroup;
this->asyncWaitGroup = new fu::WaitGroup();

if(!success) {
throw Php::Exception("Sending request to ArangoDB failed");
}
}

}}}
22 changes: 16 additions & 6 deletions src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,33 @@ namespace arangodb { namespace fuerte { namespace php {
short defaultTimeout = 3;
int threadCount;

fu::WaitGroup* asyncWaitGroup;

public:
Connection();
~Connection();

/**
* Constructor
*
* @param Php::Parameters connection options
*/
void __construct(Php::Parameters &params);

void setThreadCount(Php::Parameters &params);

void connect();
Response* sendRequest(Request* request);
void sendRequestAsync(Request* request, Php::Value& callback);

Php::Value send(Php::Parameters &params);
void sendAsync(Php::Parameters &params);

Php::Value methodDelete(Php::Parameters &params);
Php::Value methodGet(Php::Parameters &params);
Php::Value methodPost(Php::Parameters &params);
Php::Value methodPut(Php::Parameters &params);
Php::Value methodHead(Php::Parameters &params);
Php::Value methodPatch(Php::Parameters &params);
Php::Value methodOptions(Php::Parameters &params);

void wait();

virtual ~Connection() = default;
};

}}}
19 changes: 19 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,29 @@ extern "C" {
connection.method<&arangodb::fuerte::php::Connection::send>("send", {
Php::ByVal("request", "ArangoDb\\Request", true)
});
connection.method<&arangodb::fuerte::php::Connection::sendAsync>("sendAsync", {
Php::ByVal("request", "ArangoDb\\Request", true),
Php::ByVal("callback", Php::Type::Callable, true)
});
connection.method<&arangodb::fuerte::php::Connection::setThreadCount>("setThreadCount", {
Php::ByVal("threadCount", Php::Type::Numeric, true)
});

Php::Arguments methodArgs = {
Php::ByVal("path", Php::Type::String, true),
Php::ByVal("vpack", "ArangoDb\\Vpack", true)
};

connection.method<&arangodb::fuerte::php::Connection::methodDelete>("delete", methodArgs);
connection.method<&arangodb::fuerte::php::Connection::methodGet>("get", methodArgs);
connection.method<&arangodb::fuerte::php::Connection::methodPost>("post", methodArgs);
connection.method<&arangodb::fuerte::php::Connection::methodPut>("put", methodArgs);
connection.method<&arangodb::fuerte::php::Connection::methodHead>("head", methodArgs);
connection.method<&arangodb::fuerte::php::Connection::methodPatch>("patch", methodArgs);
connection.method<&arangodb::fuerte::php::Connection::methodOptions>("options", methodArgs);

connection.method<&arangodb::fuerte::php::Connection::wait>("wait");

connection.property("HOST", "host", Php::Const);
connection.property("USER", "user", Php::Const);
connection.property("PASSWORD", "password", Php::Const);
Expand Down
27 changes: 22 additions & 5 deletions src/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,38 @@

namespace arangodb { namespace fuerte { namespace php {

Request::Request(std::string path, const Vpack* vpack): path(path), builder(vpack->getBuilder())
{
}

Request::Request()
{
}

void Request::__construct(Php::Parameters &params)
{
if(!params[2].instanceOf("ArangoDb\\Vpack"))
throw Php::Exception("Expected vpack to be of type Vpack");

this->request = fu::createRequest(static_cast<fu::RestVerb>(params[0].numericValue()), params[1]);
this->vpack = (Vpack*)params[2].implementation();
this->httpMethod = static_cast<fu::RestVerb>(params[0].numericValue());
this->path = params[1].stringValue();

this->request->addVPack(this->vpack->getSlice());
this->builder = ((Vpack*)params[2].implementation())->getBuilder();
}


const fu::Request& Request::getFuerteRequest()
void Request::setHttpMethod(int8_t httpMethod)
{
return *this->request;
this->httpMethod = static_cast<fu::RestVerb>(httpMethod);
}


std::unique_ptr<fu::Request> Request::getFuerteRequest()
{
auto request = fu::createRequest(this->httpMethod, this->path);
request->addVPack(this->builder.slice());

return request;
}

}}}
11 changes: 8 additions & 3 deletions src/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ namespace arangodb { namespace fuerte { namespace php {
class Request : public Php::Base
{
private:
Vpack* vpack;
std::unique_ptr<fu::Request> request;

fu::RestVerb httpMethod;
std::string path;
vp::Builder builder;

public:
static const int8_t METHOD_DELETE = 0;
static const int8_t METHOD_GET = 1;
Expand All @@ -27,11 +30,13 @@ namespace arangodb { namespace fuerte { namespace php {
static const int8_t METHOD_PATCH = 5;
static const int8_t METHOD_OPTIONS = 6;

Request() = default;
Request(std::string path, const Vpack* vpack);
Request();

void __construct(Php::Parameters &params);
void setHttpMethod(int8_t httpMethod);

const fu::Request& getFuerteRequest();
std::unique_ptr<fu::Request> getFuerteRequest();

virtual ~Request() = default;

Expand Down
32 changes: 32 additions & 0 deletions src/response.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "response.h"

namespace arangodb { namespace fuerte { namespace php {

Response::Response(const fu::Response &response): response(response)
{
}

Php::Value Response::getHttpCode()
{
return static_cast<int>(this->response.statusCode());
}

Php::Value Response::getBody()
{
std::string body;

try {
vp::Slice slice = this->response.slices().front();
vp::Options dumperOptions;

vp::StringSink sink(&body);
vp::Dumper dumper(&sink, &dumperOptions);
dumper.dump(slice);
} catch(vp::Exception const& e) {
throw Php::Exception(e.what());
}

return body;
}

}}}
30 changes: 3 additions & 27 deletions src/response.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,11 @@ namespace arangodb { namespace fuerte { namespace php {
fu::Response response;

public:
Response(const fu::Response &response): response(response)
{
}
Response(const fu::Response &response);

Php::Value getHttpCode()
{
return static_cast<int>(this->response.statusCode());
}

Php::Value getBody()
{
std::string body;

try {
vp::Slice slice = this->response.slices().front();
vp::Options dumperOptions;

vp::StringSink sink(&body);
vp::Dumper dumper(&sink, &dumperOptions);
dumper.dump(slice);
} catch(vp::Exception const& e) {
throw Php::Exception(e.what());
}

return body;
}

virtual ~Response() = default;
Php::Value getHttpCode();

Php::Value getBody();
};

}}}
5 changes: 5 additions & 0 deletions src/vpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ namespace arangodb { namespace fuerte { namespace php {
return this->builder.slice();
}

const vp::Builder& Vpack::getBuilder() const
{
return this->builder;
}

}}}
Loading

0 comments on commit e20caf1

Please sign in to comment.