diff --git a/Makefile b/Makefile index 2f57419c7..4f2e5879d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ CXX=clang++ CFLAGS=-std=c++1y -O2 -Wall -Wno-unknown-pragmas +CFLAGS_DEBUG=-std=c++1y -Wall -Wno-unknown-pragmas -g LDFLAGS=-luv -lhttp_parser speedy/r3/.libs/libr3.a -L/usr/local/lib -lpcre -pthread INC=-I./ -I./speedy/rapidjson/include/ @@ -7,9 +8,12 @@ SOURCES=memgraph.cpp EXECUTABLE=memgraph all: $(EXECUTABLE) - -$(EXECUTABLE): $(SOURCES) - $(CXX) $(CFLAGS) $(SOURCES) -o $(EXECUTABLE) $(INC) $(LDFLAGS) + +$(EXECUTABLE): $(SOURCES) + $(CXX) $(CFLAGS) $(SOURCES) -o $(EXECUTABLE) $(INC) $(LDFLAGS) + +debug: $(SOURCES) + $(CXX) $(CFLAGS_DEBUG) $(SOURCES) -o $(EXECUTABLE) $(INC) $(LDFLAGS) .PHONY: clean: diff --git a/api/resources/node.hpp b/api/resources/node.hpp index f36d34d13..4e643654c 100644 --- a/api/resources/node.hpp +++ b/api/resources/node.hpp @@ -31,12 +31,12 @@ public: it->name.GetString(), it->value.GetString() ); } - + // commit the transaction transaction.commit(); return std::move(vertex_accessor); - }, + }, [&req, &res](Vertex::Accessor&& vertex_accessor) { return res.send( http::Status::Created, @@ -51,7 +51,7 @@ class Node : public Resource { public: using Resource::Resource; - + void get(sp::Request& req, sp::Response& res) { task->run([this, &req]() { @@ -59,7 +59,7 @@ public: auto& transaction = db->tx_engine.begin(); // read id param - Id id(std::stoull(req.params[0])); + Id id(std::stoull(req.params[0])); // find node auto vertex_accessor = db->graph.vertices.find(transaction, id); @@ -71,7 +71,10 @@ public: }, [&req, &res](Vertex::Accessor&& vertex_accessor) { if (vertex_accessor.empty()) { - return res.send(http::Status::NotFound, "The node was not found"); + return res.send( + http::Status::NotFound, + "The node was not found" + ); } return res.send( vertex_create_response(vertex_accessor) @@ -81,59 +84,72 @@ public: void put(sp::Request& req, sp::Response& res) { - // task->run([this, &req]() -> Vertex* { - // // create transaction - // auto& transaction = db->tx_engine.begin(); - - // // read id param - // Id id(std::stoull(req.params[0])); - - // // find node - // auto vertex = db->graph.vertices.update(transaction, id); - - // if (vertex == nullptr) - // return nullptr; - - // // map fields - // for(auto it = req.json.MemberBegin(); it != req.json.MemberEnd(); ++it) - // { - // vertex->data.props.set(it->name.GetString(), it->value.GetString()); - // } - // - // // commit the transaction - // transaction.commit(); - - // return vertex; - // }, - // [&req, &res](Vertex* vertex) { - // if (vertex == nullptr) { - // return res.send(http::Status::NotFound, "The node was not found"); - // } - // return res.send(vertex_props_to_string(vertex)); - // }); + task->run([this, &req]() { + // create transaction + auto& transaction = db->tx_engine.begin(); + + // read id param + Id id(std::stoull(req.params[0])); + + // find node + auto vertex_accessor = db->graph.vertices.find(transaction, id); + + if (vertex_accessor.empty()) + return std::move(vertex_accessor); + + auto begin_it = req.json.MemberBegin(); + auto end_it = req.json.MemberEnd(); + for(auto it = begin_it; it != end_it; ++it) + { + vertex_accessor.template property( + it->name.GetString(), it->value.GetString() + ); + } + + // commit the transaction + transaction.commit(); + + return std::move(vertex_accessor); + }, + [&req, &res](Vertex::Accessor&& vertex_accessor) { + if (vertex_accessor.empty()) { + return res.send( + http::Status::NotFound, + "The node was not found" + ); + } + return res.send(vertex_create_response(vertex_accessor)); + }); } void del(sp::Request& req, sp::Response& res) { - // task->run([this, &req]() -> bool { - // // create transaction - // auto& transaction = db->tx_engine.begin(); - - // // read id param - // Id id(std::stoull(req.params[0])); + task->run([this, &req]() -> bool { + // create transaction + auto& transaction = db->tx_engine.begin(); - // auto is_deleted = db->graph.vertices.remove(transaction, id); + // read id param + Id id(std::stoull(req.params[0])); - // // commit the transaction - // transaction.commit(); + auto vertex_accessor = db->graph.vertices.find(transaction, id); - // return is_deleted; - // }, - // [&req, &res](bool is_deleted) { - // if (is_deleted) - // return res.send(http::Status::Ok, "The node was deleted"); + if (vertex_accessor.empty()) + return false; - // return res.send(http::Status::NotFound, "The node was not found"); - // }); + auto is_deleted = vertex_accessor.remove(transaction); + + // commit the transaction + transaction.commit(); + + return is_deleted; + }, + // pass something smarter + // e.g. enum { NotFound, Deleted, DeletionFaild } + [&req, &res](bool is_deleted) { + if (is_deleted) + return res.send(http::Status::Ok, "The node was deleted"); + + return res.send(http::Status::NotFound, "The node was not found"); + }); } }; diff --git a/build.sh b/build.sh index 1f915bc24..ac5b5c74e 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,20 @@ #!/bin/bash +while [[ $# > 1 ]] +do +key="$1" +case $key in + -t|--target) + target="$2" + shift + ;; +esac +shift +done + +if [[ -z $target ]]; then + target="all" +fi + cd api && python link_resources.py && cd .. -make clean && make +make clean && make $target diff --git a/mvcc/version_list.hpp b/mvcc/version_list.hpp index a66a18151..45a7c9568 100644 --- a/mvcc/version_list.hpp +++ b/mvcc/version_list.hpp @@ -90,6 +90,7 @@ public: VersionList(VersionList&& other) { this->head = other.head.load(); + this->identifier = other.id(); other.head = nullptr; } @@ -222,15 +223,19 @@ private: if(!record) return false; + // TODO-buda: what is this? lock_and_validate(record, t); return remove(record, t), true; } - void remove(T* record, tx::Transaction& t) + // TODO-buda: this whole part is questionable + bool remove(T* record, tx::Transaction& t) { assert(record != nullptr); lock_and_validate(record, t); record->mark_deleted(t); + // TODO-buda: is this ok, at least for now? + return true; } void lock_and_validate(T* record, tx::Transaction& t) diff --git a/speedy/rapidjson_middleware.hpp b/speedy/rapidjson_middleware.hpp index 9164593e1..7b0228f5d 100644 --- a/speedy/rapidjson_middleware.hpp +++ b/speedy/rapidjson_middleware.hpp @@ -13,6 +13,11 @@ namespace sp bool rapidjson_middleware(sp::Request& req, sp::Response& res) { + // TODO-buda: sometimes req.body is unvalid + // when python requests lib send {} as data + // req.body is broken and the next if is not executed + // as it supposed to be + // the body is empty and json parsing isn't necessary if (req.body.empty()) return true; diff --git a/storage/record_accessor.hpp b/storage/record_accessor.hpp index e70259970..5222880ca 100644 --- a/storage/record_accessor.hpp +++ b/storage/record_accessor.hpp @@ -32,7 +32,7 @@ public: assert(!empty()); auto accessor = vlist->access(t); - return Derived(accessor->update(t), vlist, store); + return Derived(accessor.update(t), vlist, store); } bool remove(tx::Transaction& t) const @@ -40,7 +40,7 @@ public: assert(!empty()); auto accessor = vlist->access(t); - return accessor->remove(t); + return accessor.remove(record); } const Property* property(const std::string& key) const diff --git a/storage/vertices.hpp b/storage/vertices.hpp index b87d8fead..10f922fdd 100644 --- a/storage/vertices.hpp +++ b/storage/vertices.hpp @@ -17,7 +17,7 @@ public: // find vertex auto versions_accessor = vertices_iterator->second.access(t); auto vertex = versions_accessor.find(); - + return Vertex::Accessor(vertex, &vertices_iterator->second, this); } @@ -25,20 +25,23 @@ public: { // get next vertex id auto next = counter.next(std::memory_order_acquire); - + // create new vertex record VertexRecord vertex_record; vertex_record.id(next); - + // insert the new vertex record into the vertex store auto vertices_accessor = vertices.access(); - auto result = vertices_accessor.insert_unique(next, std::move(vertex_record)); - + auto result = vertices_accessor.insert_unique( + next, + std::move(vertex_record) + ); + // create new vertex auto inserted_vertex_record = result.first; auto vertex_accessor = inserted_vertex_record->second.access(t); auto vertex = vertex_accessor.insert(); - + return Vertex::Accessor(vertex, &inserted_vertex_record->second, this); } diff --git a/test/unit/http_api/vertex_crud_test.py b/test/unit/http_api/vertex_crud_test.py index 81e7ea13c..dd6bd8594 100644 --- a/test/unit/http_api/vertex_crud_test.py +++ b/test/unit/http_api/vertex_crud_test.py @@ -6,7 +6,7 @@ import requests class VertexCrudTest(unittest.TestCase): - def check_reponse_status_code(self, r, code): + def check_response_status_code(self, r, code): ''' Checks status code of the response and returns response data as json. @@ -15,8 +15,6 @@ class VertexCrudTest(unittest.TestCase): response data (json) ''' self.assertEqual(r.status_code, code) - response = r.json() - return response def check_metadata_and_id(self, response, id=None): ''' @@ -46,7 +44,8 @@ class VertexCrudTest(unittest.TestCase): ''' resource_url = self.endpoint + '/%s' % resource_id r = requests.get(resource_url) - response = self.check_reponse_status_code(r, 200) + self.check_response_status_code(r, 200) + response = r.json() self.check_metadata_and_id(response, resource_id) self.check_response_data(response, valid_data) @@ -63,17 +62,22 @@ class VertexCrudTest(unittest.TestCase): # 1. create r = requests.post(self.endpoint, json=create_payload) - response = self.check_reponse_status_code(r, 201) + self.check_response_status_code(r, 201) + response = r.json() self.resource_id = self.check_metadata_and_id(response) self.resource_url = self.endpoint + "/%s" % self.resource_id + print("Id: %s Url: %s" % (str(self.resource_id), + str(self.resource_url))) self.check_response_data(response, create_payload) # 2. read self.check_read(self.resource_id, create_payload) # 3. update - r = requests.put(self.resource_url, edit_payload) - self.check_reponse_status_code(r, 200) + r = requests.put(self.resource_url, json=edit_payload) + # TODO-buda: check this also + # r = requests.put(self.resource_url, {}) + self.check_response_status_code(r, 200) # 4. read self.check_read(self.resource_id, edited_resource) @@ -85,3 +89,6 @@ class VertexCrudTest(unittest.TestCase): # 6. read r = requests.get(self.resource_url) self.check_response_status_code(r, 404) + +if __name__ == '__main__': + unittest.main()