From e89da5f8756bbbccfaa1af9ed0dd567f0b3a29af Mon Sep 17 00:00:00 2001
From: Marko Budiselic <mbudiselicbuda@gmail.com>
Date: Sat, 2 Jan 2016 22:20:09 +0100
Subject: [PATCH] reconstructed rest api, but still this is broken version,
 TODO: discuss where is place for the id (versions accessor, versions or in
 vertex accessor

---
 api/resources/node.hpp         | 103 +++++++++++++++++----------------
 api/response_json.hpp          |  10 ++--
 mvcc/record.hpp                |   2 +-
 mvcc/version_list.hpp          |  27 +++++++--
 storage/edge_proxy.hpp         |   9 ---
 storage/model/label_list.hpp   |   3 +-
 storage/model/vertex_model.hpp |   4 +-
 storage/record_accessor.hpp    |  17 ++++--
 storage/record_proxy.hpp       |  79 -------------------------
 storage/vertex.hpp             |   4 +-
 storage/vertex_accessor.hpp    |   9 +--
 storage/vertex_proxy.hpp       |  10 ----
 storage/vertices.hpp           |  46 ++++++++++-----
 transactions/lock_store.hpp    |   2 +-
 transactions/transaction.hpp   |   2 +-
 15 files changed, 135 insertions(+), 192 deletions(-)
 delete mode 100644 storage/edge_proxy.hpp
 delete mode 100644 storage/record_proxy.hpp
 delete mode 100644 storage/vertex_proxy.hpp

diff --git a/api/resources/node.hpp b/api/resources/node.hpp
index c4db74ca1..f36d34d13 100644
--- a/api/resources/node.hpp
+++ b/api/resources/node.hpp
@@ -6,6 +6,7 @@
 #include "mvcc/version_list.hpp"
 #include "api/response_json.hpp"
 #include "api/restful/resource.hpp"
+#include "storage/model/properties/property.hpp"
 
 #pragma url /node
 class Nodes : public Resource<Nodes, POST>
@@ -20,13 +21,13 @@ public:
             auto& transaction = db->tx_engine.begin();
 
             // insert a new vertex
-            auto vertex_proxy = db->graph.vertices.insert(transaction);
+            auto vertex_accessor = db->graph.vertices.insert(transaction);
 
             auto begin_it = req.json.MemberBegin();
             auto end_it = req.json.MemberEnd();
             for(auto it = begin_it; it != end_it; ++it)
             {
-                vertex_proxy.property(
+                vertex_accessor.template property<String>(
                     it->name.GetString(), it->value.GetString()
                 );
             }
@@ -34,12 +35,12 @@ public:
             // commit the transaction
             transaction.commit();
 
-            return std::move(vertex_proxy);
+            return std::move(vertex_accessor);
         }, 
-        [&req, &res](VertexProxy&& vertex_proxy) {
+        [&req, &res](Vertex::Accessor&& vertex_accessor) {
             return res.send(
                 http::Status::Created,
-                vertex_create_response(vertex_proxy)
+                vertex_create_response(vertex_accessor)
             );
         });
     }
@@ -61,76 +62,78 @@ public:
             Id id(std::stoull(req.params[0])); 
 
             // find node
-            auto vertex = db->graph.vertices.find(transaction, id);
+            auto vertex_accessor = db->graph.vertices.find(transaction, id);
 
             // commit the transaction
             transaction.commit();
 
-            return vertex;
+            return std::move(vertex_accessor);
         },
-        [&req, &res](const Vertex* vertex) {
-            if (vertex == nullptr) {
+        [&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_props_to_string(vertex));
+            return res.send(
+                vertex_create_response(vertex_accessor)
+            );
         });
     }
 
     void put(sp::Request& req, sp::Response& res)
     {
-        task->run([this, &req]() -> Vertex* {
-             // create transaction
-             auto& transaction = db->tx_engine.begin();
+        // task->run([this, &req]() -> Vertex* {
+        //      // create transaction
+        //      auto& transaction = db->tx_engine.begin();
  
-             // read id param
-             Id id(std::stoull(req.params[0])); 
+        //      // read id param
+        //      Id id(std::stoull(req.params[0])); 
  
-             // find node
-             auto vertex = db->graph.vertices.update(transaction, id);
+        //      // find node
+        //      auto vertex = db->graph.vertices.update(transaction, id);
  
-             if (vertex == nullptr)
-                 return nullptr;
+        //      if (vertex == nullptr)
+        //          return nullptr;
  
-             // map fields
-             for(auto it = req.json.MemberBegin(); it != req.json.MemberEnd(); ++it)
-             {
-                  vertex->data.props.set<String>(it->name.GetString(), it->value.GetString());
-             }
-             
-             // commit the transaction
-             transaction.commit();
+        //      // map fields
+        //      for(auto it = req.json.MemberBegin(); it != req.json.MemberEnd(); ++it)
+        //      {
+        //           vertex->data.props.set<String>(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));
-        });
+        //      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));
+        // });
     }
 
     void del(sp::Request& req, sp::Response& res)
     {
-         task->run([this, &req]() -> bool {
-             // create transaction
-             auto& transaction = db->tx_engine.begin();
+         // task->run([this, &req]() -> bool {
+         //     // create transaction
+         //     auto& transaction = db->tx_engine.begin();
  
-             // read id param
-             Id id(std::stoull(req.params[0]));
+         //     // read id param
+         //     Id id(std::stoull(req.params[0]));
 
-             auto is_deleted = db->graph.vertices.remove(transaction, id);
+         //     auto is_deleted = db->graph.vertices.remove(transaction, id);
 
-             // commit the transaction
-             transaction.commit();
+         //     // commit the transaction
+         //     transaction.commit();
 
-             return is_deleted;
-         },
-         [&req, &res](bool is_deleted) {
-            if (is_deleted)
-                return res.send(http::Status::Ok, "The node was deleted");
+         //     return is_deleted;
+         // },
+         // [&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");
-         });
+         //    return res.send(http::Status::NotFound, "The node was not found");
+         // });
     }
 };
diff --git a/api/response_json.hpp b/api/response_json.hpp
index 26b676d4a..8a0a26231 100644
--- a/api/response_json.hpp
+++ b/api/response_json.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "storage/vertex.hpp"
-#include "storage/vertex_proxy.hpp"
+#include "storage/vertex_accessor.hpp"
 #include "storage/writer/rapidjson_stringwriter.hpp"
 
 StringBuffer vertex_props_to_buffer(const Vertex* vertex)
@@ -29,7 +29,7 @@ using RJStringBuffer = rapidjson::StringBuffer;
 using RJStringWriter = rapidjson::Writer<RJStringBuffer>;
 using ptr_RJStringWriter = std::shared_ptr<RJStringWriter>;
 
-std::string vertex_create_response(const VertexProxy& vertex_proxy)
+std::string vertex_create_response(const Vertex::Accessor& vertex_accessor)
 {
     // make a string buffer
     RJStringBuffer buffer;
@@ -40,14 +40,14 @@ std::string vertex_create_response(const VertexProxy& vertex_proxy)
 
     writer->StartObject();
     writer->String("id");
-    writer->Int64(vertex_proxy.record_id());
+    writer->Int64(vertex_accessor.id());
     writer->EndObject();
 
     writer->String("data");
     writer->StartObject();
     RapidJsonStringWriter dataBuffer(writer);
-    auto vertex = vertex_proxy.record_version();
-    vertex->data.props.accept(dataBuffer);
+    auto properties = vertex_accessor.properties();
+    properties.accept(dataBuffer);
     writer->EndObject();
 
     writer->EndObject();
diff --git a/mvcc/record.hpp b/mvcc/record.hpp
index 7896a95f5..5395b21c9 100644
--- a/mvcc/record.hpp
+++ b/mvcc/record.hpp
@@ -8,7 +8,7 @@
 #include "cre_exp.hpp"
 #include "version.hpp"
 #include "hints.hpp"
-#include "database/locking/record_lock.hpp"
+#include "storage/locking/record_lock.hpp"
 
 // the mvcc implementation used here is very much like postgresql's
 // more info: https://momjian.us/main/writings/pgsql/mvcc.pdf
diff --git a/mvcc/version_list.hpp b/mvcc/version_list.hpp
index b6f44dd0d..a66a18151 100644
--- a/mvcc/version_list.hpp
+++ b/mvcc/version_list.hpp
@@ -45,7 +45,7 @@ public:
             return vlist.insert(transaction);
         }
 
-        const T* find() const
+        T* find() const
         {
             return vlist.find(transaction);
         }
@@ -72,7 +72,7 @@ public:
 
         const Id& id() const
         {
-            return vlist.id;
+            return vlist.identifier;
         }
 
     private:
@@ -129,11 +129,21 @@ public:
 
     }
 
+    const Id& id() const
+    {
+        return identifier;
+    }
+
+    void id(const Id& identifier)
+    {
+        this->identifier = identifier;
+    }
+
 private:
     std::atomic<T*> head {nullptr};
     RecordLock lock;
 
-    Id id;
+    Id identifier;
 
     //static Recycler recycler;
 
@@ -157,10 +167,11 @@ private:
         return r;
     }
 
-    T* insert(tx::Transaction& t, const Id& id)
+    T* insert(tx::Transaction& t)
     {
         assert(head == nullptr);
-        this->id = id;
+
+        // this->id = id;
 
         // create a first version of the record
         // TODO replace 'new' with something better
@@ -242,3 +253,9 @@ private:
 };
 
 }
+
+class Vertex;
+class Edge;
+
+using VertexRecord = mvcc::VersionList<Vertex>;
+using EdgeRecord = mvcc::VersionList<Edge>;
diff --git a/storage/edge_proxy.hpp b/storage/edge_proxy.hpp
deleted file mode 100644
index e7ac14254..000000000
--- a/storage/edge_proxy.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "record_proxy.hpp"
-#include "edges.hpp"
-
-class EdgeProxy : public RecordProxy<Edge, Edges, EdgeProxy>
-{
-    // TODO: implementation
-};
diff --git a/storage/model/label_list.hpp b/storage/model/label_list.hpp
index a9d123d8c..0f0d9fea7 100644
--- a/storage/model/label_list.hpp
+++ b/storage/model/label_list.hpp
@@ -24,8 +24,7 @@ public:
         return labels.count(label);
     }
 
-    size_t count() const
-    {
+    size_t count() const {
         return labels.size();
     }
 
diff --git a/storage/model/vertex_model.hpp b/storage/model/vertex_model.hpp
index b04f32184..b19c48388 100644
--- a/storage/model/vertex_model.hpp
+++ b/storage/model/vertex_model.hpp
@@ -1,12 +1,12 @@
 #pragma once
 
 #include "property_model.hpp"
-#include "label_list.hpp"
+// #include "label_list.hpp"
 #include "edge_list.hpp"
 
 class VertexModel : public PropertyModel
 {
 public:
     EdgeList in, out;
-    LabelList labels;
+    // LabelList labels;
 };
diff --git a/storage/record_accessor.hpp b/storage/record_accessor.hpp
index 567fc5669..e70259970 100644
--- a/storage/record_accessor.hpp
+++ b/storage/record_accessor.hpp
@@ -3,6 +3,7 @@
 #include "transactions/transaction.hpp"
 #include "mvcc/version_list.hpp"
 #include "storage/model/properties/property.hpp"
+#include "storage/model/properties/properties.hpp"
 
 template <class T, class Store, class Derived>
 class RecordAccessor
@@ -18,8 +19,7 @@ public:
 
     const Id& id() const
     {
-        auto accessor = vlist->access();
-        return accessor.id();
+        return vlist->id();
     }
 
     bool empty() const
@@ -31,7 +31,7 @@ public:
     {
         assert(!empty());
 
-        auto accessor = vlist->access();
+        auto accessor = vlist->access(t);
         return Derived(accessor->update(t), vlist, store);
     }
 
@@ -39,19 +39,24 @@ public:
     {
         assert(!empty());
 
-        auto accessor = vlist->access();
+        auto accessor = vlist->access(t);
         return accessor->remove(t);
     }
 
     const Property* property(const std::string& key) const
     {
-        return record->props.at(key);
+        return record->data.props.at(key);
     }
 
     template <class V, class... Args>
     void property(const std::string& key, Args&&... args)
     {
-        record->props.template set<V>(key, std::forward<Args>(args)...);
+        record->data.props.template set<V>(key, std::forward<Args>(args)...);
+    }
+
+    Properties& properties() const
+    {
+        return record->data.props;
     }
 
 protected:
diff --git a/storage/record_proxy.hpp b/storage/record_proxy.hpp
deleted file mode 100644
index 8af317264..000000000
--- a/storage/record_proxy.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include "transactions/transaction.hpp"
-#include "mvcc/version_list.hpp"
-#include "storage/model/properties/property.hpp"
-
-template <typename T, typename Store, typename Derived>
-class RecordProxy
-{
-public:
-    RecordProxy(
-        const Id& id,
-        T* version,
-        Store *store,
-        mvcc::VersionList<T> *version_list) :
-        id(id), version(version), store(store), version_list(version_list)
-    {
-    }
-
-    RecordProxy(const RecordProxy& record_proxy) = delete;
-
-    RecordProxy(RecordProxy&& other) :
-        id(other.id), version(other.version), store(other.store),
-        version_list(other.version_list)
-    {
-        other.id = 0; // TODO: not very good idea because
-        // replace with something else
-        other.version = nullptr;
-        other.store = nullptr;
-        other.version_list = nullptr;
-    }
-
-    ~RecordProxy()
-    {
-        // TODO: implementation
-    }
-
-    Derived update(tx::Transaction& transaction) const
-    {
-        // TODO: implementation
-        transaction.commit();
-        return nullptr;
-    }
-
-    void remove(tx::Transaction& transaction) const
-    {
-        // TODO: implementation
-        transaction.commit();
-    }
-
-    template<typename K>
-    Property* property(const K& key) const
-    {
-        return version->data.props.find(key);
-    }
-   
-    template<typename K, typename V> 
-    void property(const K& key, const V& value)
-    {
-        version->data.props.template set<String>(key, value);
-        // TODO: update the index
-    }
-
-    Id record_id() const
-    {
-        return id;
-    }
-
-    T* record_version() const
-    {
-        return version;
-    }
-
-private:
-    Id id;
-    T* version;
-    Store *store;
-    mvcc::VersionList<T> *version_list;
-};
diff --git a/storage/vertex.hpp b/storage/vertex.hpp
index 812b79060..4d534cd78 100644
--- a/storage/vertex.hpp
+++ b/storage/vertex.hpp
@@ -1,8 +1,8 @@
 #pragma once
 
-#include "model/properties/jsonwriter.hpp"
-#include "model/vertex_model.hpp"
 #include "mvcc/record.hpp"
+#include "model/vertex_model.hpp"
+#include "model/properties/jsonwriter.hpp"
 
 class Vertex : public mvcc::Record<Vertex>
 {
diff --git a/storage/vertex_accessor.hpp b/storage/vertex_accessor.hpp
index b02c4baaa..8c11bac4c 100644
--- a/storage/vertex_accessor.hpp
+++ b/storage/vertex_accessor.hpp
@@ -1,10 +1,11 @@
 #pragma once
 
-#include "record_accessor.hpp"
-#include "vertex.hpp"
-#include "vertices.hpp"
+#include "storage/vertex.hpp"
+#include "storage/record_accessor.hpp"
 
-class Vertex::Accessor : public RecordAccessor<Vertex, Vertices, Accessor>
+class Vertices;
+
+class Vertex::Accessor : public RecordAccessor<Vertex, Vertices, Vertex::Accessor>
 {
 public:
     using RecordAccessor::RecordAccessor;
diff --git a/storage/vertex_proxy.hpp b/storage/vertex_proxy.hpp
deleted file mode 100644
index bf7831ed4..000000000
--- a/storage/vertex_proxy.hpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#include "record_proxy.hpp"
-
-class Vertices;
-
-class VertexProxy : public RecordProxy<Vertex, Vertices, VertexProxy>
-{
-    using RecordProxy::RecordProxy;
-};
diff --git a/storage/vertices.hpp b/storage/vertices.hpp
index 3df3bfc45..b87d8fead 100644
--- a/storage/vertices.hpp
+++ b/storage/vertices.hpp
@@ -1,34 +1,50 @@
 #pragma once
 
-#include "vertex.hpp"
 #include "common.hpp"
-#include "vertex_proxy.hpp"
+#include "storage/vertex_accessor.hpp"
 
 class Vertices
 {
 public:
-    const Vertex* find(tx::Transaction& transaction, const Id& id)
+    Vertex::Accessor find(tx::Transaction& t, const Id& id)
     {
-        // find vertex record
         auto vertices_accessor = vertices.access();
-        auto vertex_record = vertices_accessor.find(id);
+        auto vertices_iterator = vertices_accessor.find(id);
 
-        if (vertex_record == vertices_accessor.end())
-            return nullptr;
+        if (vertices_iterator == vertices_accessor.end())
+            return Vertex::Accessor();
 
         // find vertex
-        auto vertex_accessor = vertex_record->second.access(transaction);
-        auto vertex = vertex_accessor.find();
+        auto versions_accessor = vertices_iterator->second.access(t);
+        auto vertex = versions_accessor.find();
+        
+        return Vertex::Accessor(vertex, &vertices_iterator->second, this);
+    }
 
-        // TODO: here is problem to create vertex_proxy because vertex
-        // is const pointer
-
-        return vertex;
+    Vertex::Accessor insert(tx::Transaction& t)
+    {
+        // 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));
+        
+        // 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);
     }
 
 private:
-    Indexes indexes;
+    // Indexes indexes;
 
-    SkipList<uint64_t, VersionList<Vertex>> vertices;
+    SkipList<uint64_t, VertexRecord> vertices;
     AtomicCounter<uint64_t> counter;
 };
diff --git a/transactions/lock_store.hpp b/transactions/lock_store.hpp
index 5b3334487..6afe19752 100644
--- a/transactions/lock_store.hpp
+++ b/transactions/lock_store.hpp
@@ -3,7 +3,7 @@
 #include <vector>
 #include <cassert>
 #include <memory>
-#include "database/locking/lock_status.hpp"
+#include "storage/locking/lock_status.hpp"
 
 namespace tx
 {
diff --git a/transactions/transaction.hpp b/transactions/transaction.hpp
index f68a1fe37..a8e44f44c 100644
--- a/transactions/transaction.hpp
+++ b/transactions/transaction.hpp
@@ -7,7 +7,7 @@
 #include "mvcc/id.hpp"
 #include "snapshot.hpp"
 #include "lock_store.hpp"
-#include "database/locking/record_lock.hpp"
+#include "storage/locking/record_lock.hpp"
 
 namespace tx
 {