From 1849514159aee94f6783f957ae7a0c6a945ee068 Mon Sep 17 00:00:00 2001
From: Kruno Tomola Fabro <krunotf@memgraph.io>
Date: Fri, 12 Aug 2016 23:01:39 +0100
Subject: [PATCH] First step in database accessor refactoring done. It's
 compiling. All tests with exception of integration_querys pass

---
 CMakeLists.txt                                | 10 ++-
 .../bolt/v1/serialization/bolt_serializer.hpp | 72 ++++++-----------
 include/database/db.hpp                       | 13 ++--
 include/database/db_accessor.hpp              | 50 ++++++++++++
 include/database/db_transaction.hpp           | 26 +++++++
 include/query_engine/hardcode/queries.hpp     | 72 ++++++++---------
 include/storage/edge_accessor.hpp             | 24 +++---
 include/storage/edges.hpp                     |  4 +-
 include/storage/record_accessor.hpp           | 28 ++++---
 include/storage/vertex_accessor.hpp           |  5 +-
 include/storage/vertices.hpp                  | 11 +--
 poc/astar.cpp                                 | 57 +++++++-------
 src/cypher/tokenizer/cypher_lexer.hpp         |  4 +-
 src/database/db.cpp                           |  6 ++
 src/database/db_accessor.cpp                  | 77 +++++++++++++++++++
 src/database/db_transaction.cpp               |  8 ++
 src/storage/edge_accessor.cpp                 | 29 +++++++
 src/storage/edges.cpp                         | 16 ++--
 src/storage/vertex_accessor.cpp               | 13 ++--
 src/storage/vertices.cpp                      | 33 ++++----
 20 files changed, 359 insertions(+), 199 deletions(-)
 create mode 100644 include/database/db_accessor.hpp
 create mode 100644 include/database/db_transaction.hpp
 create mode 100644 src/database/db.cpp
 create mode 100644 src/database/db_accessor.cpp
 create mode 100644 src/database/db_transaction.cpp
 create mode 100644 src/storage/edge_accessor.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 74df3c068..9efec42c3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@ find_package(Threads REQUIRED)
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
 
 # glibcxx debug (useful for gdb)
-# the problem is that the query engine doesn't work as it should work if 
+# the problem is that the query engine doesn't work as it should work if
 # this flag is present
 # TODO: find more appropriate way to use this flag only when it is needed
 # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
@@ -288,7 +288,7 @@ endif()
 
 # release flags
 set(CMAKE_CXX_FLAGS_RELEASE
-    "${CMAKE_CXX_FLAGS_RELEASE} -march=native -Wall -Werror")
+    "${CMAKE_CXX_FLAGS_RELEASE} -march=native -Wall")
 
 # -- configure defines -- default is ON | true | enabled ----------------------
 # -- logging ------------------------------------------------------------------
@@ -412,6 +412,10 @@ set(memgraph_src_files
     ${src_dir}/logging/default.cpp
     ${src_dir}/logging/log.cpp
     ${src_dir}/io/network/tls.cpp
+    ${src_dir}/database/db.cpp
+    ${src_dir}/database/db_accessor.cpp
+    ${src_dir}/database/db_transaction.cpp
+    ${src_dir}/storage/edge_accessor.cpp
 )
 
 # STATIC library used by memgraph executables
@@ -434,7 +438,7 @@ endif()
 
 # memgraph build name
 execute_process(
-    OUTPUT_VARIABLE COMMIT_NO 
+    OUTPUT_VARIABLE COMMIT_NO
     COMMAND git rev-list --count HEAD
 )
 execute_process(
diff --git a/include/communication/bolt/v1/serialization/bolt_serializer.hpp b/include/communication/bolt/v1/serialization/bolt_serializer.hpp
index 6d7248b6f..f73f41d28 100644
--- a/include/communication/bolt/v1/serialization/bolt_serializer.hpp
+++ b/include/communication/bolt/v1/serialization/bolt_serializer.hpp
@@ -1,13 +1,13 @@
 #pragma once
 
-#include "communication/bolt/v1/transport/bolt_encoder.hpp"
 #include "communication/bolt/v1/packing/codes.hpp"
+#include "communication/bolt/v1/transport/bolt_encoder.hpp"
 
-#include "storage/vertex_accessor.hpp"
 #include "storage/edge_accessor.hpp"
+#include "storage/vertex_accessor.hpp"
 
-#include "storage/model/properties/properties.hpp"
 #include "storage/model/properties/all.hpp"
+#include "storage/model/properties/properties.hpp"
 
 namespace bolt
 {
@@ -22,7 +22,7 @@ class BoltSerializer
     // friend void accept(const Property &property, Handler &h);
 
 public:
-    BoltSerializer(Stream& stream) : encoder(stream) {}
+    BoltSerializer(Stream &stream) : encoder(stream) {}
 
     /* Serializes the vertex accessor into the packstream format
      *
@@ -33,7 +33,7 @@ public:
      * }
      *
      */
-    void write(const Vertex::Accessor& vertex)
+    void write(const Vertex::Accessor &vertex)
     {
         // write signatures for the node struct and node data type
         encoder.write_struct_header(3);
@@ -47,7 +47,7 @@ public:
 
         encoder.write_list_header(labels.size());
 
-        for(auto& label : labels)
+        for (auto &label : labels)
             encoder.write_string(label.get());
 
         // write the property map
@@ -55,7 +55,7 @@ public:
 
         encoder.write_map_header(props.size());
 
-        for(auto& prop : props) {
+        for (auto &prop : props) {
             write(prop.first);
             write(*prop.second);
         }
@@ -72,7 +72,7 @@ public:
      * }
      *
      */
-    void write(const Edge::Accessor& edge)
+    void write(const Edge::Accessor &edge)
     {
         // write signatures for the edge struct and edge data type
         encoder.write_struct_header(5);
@@ -82,8 +82,8 @@ public:
         encoder.write_integer(edge.id());
 
         // TODO refactor when from() and to() start returning Accessors
-        encoder.write_integer(edge.from()->id);
-        encoder.write_integer(edge.to()->id);
+        encoder.write_integer(edge.from_record()->id);
+        encoder.write_integer(edge.to_record()->id);
 
         // write the type of the edge
         encoder.write_string(edge.edge_type());
@@ -93,65 +93,37 @@ public:
 
         encoder.write_map_header(props.size());
 
-        for(auto& prop : props) {
+        for (auto &prop : props) {
             write(prop.first);
             write(*prop.second);
         }
     }
 
-    void write(const Property& prop)
-    {
-        accept(prop, *this);
-    }
+    void write(const Property &prop) { accept(prop, *this); }
 
-    void write_null()
-    {
-        encoder.write_null();
-    }
+    void write_null() { encoder.write_null(); }
 
-    void write(const Bool& prop)
-    {
-        encoder.write_bool(prop.value());
-    }
+    void write(const Bool &prop) { encoder.write_bool(prop.value()); }
 
-    void write(const Float& prop)
-    {
-        encoder.write_double(prop.value);
-    }
+    void write(const Float &prop) { encoder.write_double(prop.value); }
 
-    void write(const Double& prop)
-    {
-        encoder.write_double(prop.value);
-    }
+    void write(const Double &prop) { encoder.write_double(prop.value); }
 
-    void write(const Int32& prop)
-    {
-        encoder.write_integer(prop.value);
-    }
+    void write(const Int32 &prop) { encoder.write_integer(prop.value); }
 
-    void write(const Int64& prop)
-    {
-        encoder.write_integer(prop.value);
-    }
+    void write(const Int64 &prop) { encoder.write_integer(prop.value); }
 
-    void write(const std::string& value)
-    {
-        encoder.write_string(value);
-    }
+    void write(const std::string &value) { encoder.write_string(value); }
 
-    void write(const String& prop)
-    {
-        encoder.write_string(prop.value);
-    }
+    void write(const String &prop) { encoder.write_string(prop.value); }
 
     template <class T>
-    void handle(const T& prop)
+    void handle(const T &prop)
     {
         write(prop);
     }
 
 protected:
-    Stream& encoder;
+    Stream &encoder;
 };
-
 }
diff --git a/include/database/db.hpp b/include/database/db.hpp
index 8cee20063..626bb7dd7 100644
--- a/include/database/db.hpp
+++ b/include/database/db.hpp
@@ -1,25 +1,22 @@
 #pragma once
 
 #include "storage/graph.hpp"
+// #include "transactions/commit_log.hpp"
 #include "transactions/engine.hpp"
-#include "transactions/commit_log.hpp"
 
 class Db
 {
 public:
     using sptr = std::shared_ptr<Db>;
 
-    Db() = default;
-    Db(const std::string& name) : name_(name) {}
-    Db(const Db& db) = delete;
+    Db();
+    Db(const std::string &name);
+    Db(const Db &db) = delete;
 
     Graph graph;
     tx::Engine tx_engine;
 
-    std::string& name()
-    {
-        return name_;
-    }
+    std::string &name();
 
 private:
     std::string name_;
diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp
new file mode 100644
index 000000000..277a24171
--- /dev/null
+++ b/include/database/db_accessor.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "database/db.hpp"
+#include "database/db_accessor.hpp"
+#include "storage/record_accessor.hpp"
+#include "storage/vertex.hpp"
+#include "storage/vertex_accessor.hpp"
+#include "storage/vertices.hpp"
+#include "transactions/transaction.hpp"
+
+class DbAccessor
+{
+public:
+    DbAccessor(Db &db);
+
+    // VERTEX METHODS
+    Vertices::vertices_t::Accessor vertex_access();
+
+    const Vertex::Accessor vertex_find(const Id &id);
+
+    const Vertex::Accessor vertex_first();
+
+    Vertex::Accessor vertex_insert();
+
+    // EDGE METHODS
+    Edge::Accessor edge_find(const Id &id);
+
+    Edge::Accessor edge_insert(VertexRecord *from, VertexRecord *to);
+
+    // LABEL METHODS
+    const Label &label_find_or_create(const std::string &name);
+
+    bool label_contains(const std::string &name);
+
+    VertexIndexRecordCollection &label_find_index(const Label &label);
+
+    // TYPE METHODS
+    const EdgeType &type_find_or_create(const std::string &name);
+
+    bool type_contains(const std::string &name);
+
+    // TRANSACTION METHODS
+    void commit();
+    void abort();
+
+    // EASE OF USE METHODS
+    tx::Transaction &operator*();
+
+    DbTransaction db;
+};
diff --git a/include/database/db_transaction.hpp b/include/database/db_transaction.hpp
new file mode 100644
index 000000000..5ddbbbc23
--- /dev/null
+++ b/include/database/db_transaction.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "storage/indexes/index_record.hpp"
+#include "storage/label/label.hpp"
+#include "transactions/transaction.hpp"
+
+class Db;
+class DbAccessor;
+
+// Inner structures local to transaction can hold ref to this structure and use
+// its methods.
+class DbTransaction
+{
+    friend DbAccessor;
+
+public:
+    DbTransaction(Db &db, tx::Transaction &trans) : db(db), trans(trans) {}
+
+    void update_label_index(const Label &label,
+                            VertexIndexRecord &&index_record);
+    // protected:
+    // TRANSACTION METHODS
+    tx::Transaction &trans;
+
+    Db &db;
+};
diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index 0c19af658..9bce411e2 100644
--- a/include/query_engine/hardcode/queries.hpp
+++ b/include/query_engine/hardcode/queries.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "database/db.hpp"
+#include "database/db_accessor.hpp"
 #include "query_engine/query_stripper.hpp"
 #include "query_engine/util.hpp"
 #include "storage/model/properties/property.hpp"
@@ -12,8 +13,8 @@ auto load_queries(Db &db)
 
     // CREATE (n {prop: 0}) RETURN n)
     auto create_node = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
-        auto vertex_accessor = db.graph.vertices.insert(t);
+        DbAccessor t(db);
+        auto vertex_accessor = t.vertex_insert();
         vertex_accessor.property("prop", args[0]);
         t.commit();
         return true;
@@ -21,10 +22,10 @@ auto load_queries(Db &db)
     queries[11597417457737499503u] = create_node;
 
     auto create_labeled_and_named_node = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
-        auto vertex_accessor = db.graph.vertices.insert(t);
+        DbAccessor t(db);
+        auto vertex_accessor = t.vertex_insert();
         vertex_accessor.property("name", args[0]);
-        auto &label = db.graph.label_store.find_or_create("LABEL");
+        auto &label = t.label_find_or_create("LABEL");
         vertex_accessor.add_label(label);
         cout_properties(vertex_accessor.properties());
         t.commit();
@@ -32,13 +33,13 @@ auto load_queries(Db &db)
     };
 
     auto create_account = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
-        auto vertex_accessor = db.graph.vertices.insert(t);
+        DbAccessor t(db);
+        auto vertex_accessor = t.vertex_insert();
         vertex_accessor.property("id", args[0]);
         vertex_accessor.property("name", args[1]);
         vertex_accessor.property("country", args[2]);
         vertex_accessor.property("created_at", args[3]);
-        auto &label = db.graph.label_store.find_or_create("ACCOUNT");
+        auto &label = t.label_find_or_create("ACCOUNT");
         vertex_accessor.add_label(label);
         cout_properties(vertex_accessor.properties());
         t.commit();
@@ -46,9 +47,9 @@ auto load_queries(Db &db)
     };
 
     auto find_node_by_internal_id = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
+        DbAccessor t(db);
         auto id = static_cast<Int32 &>(*args[0]);
-        auto vertex_accessor = db.graph.vertices.find(t, Id(id.value));
+        auto vertex_accessor = t.vertex_find(Id(id.value));
         if (!vertex_accessor) {
             cout << "vertex doesn't exist" << endl;
             t.commit();
@@ -64,20 +65,17 @@ auto load_queries(Db &db)
     };
 
     auto create_edge = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
+        DbAccessor t(db);
 
-        auto v1 = db.graph.vertices.find(t, args[0]->as<Int32>().value);
+        auto v1 = t.vertex_find(args[0]->as<Int32>().value);
         if (!v1) return t.commit(), false;
 
-        auto v2 = db.graph.vertices.find(t, args[1]->as<Int32>().value);
+        auto v2 = t.vertex_find(args[1]->as<Int32>().value);
         if (!v2) return t.commit(), false;
 
-        auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
+        auto edge_accessor = t.edge_insert(v1.vlist, v2.vlist);
 
-        v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
-        v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
-
-        auto &edge_type = db.graph.edge_type_store.find_or_create("IS");
+        auto &edge_type = t.type_find_or_create("IS");
         edge_accessor.edge_type(edge_type);
 
         t.commit();
@@ -90,8 +88,8 @@ auto load_queries(Db &db)
     };
 
     auto find_edge_by_internal_id = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
-        auto edge_accessor = db.graph.edges.find(t, args[0]->as<Int32>().value);
+        DbAccessor t(db);
+        auto edge_accessor = t.edge_find(args[0]->as<Int32>().value);
         if (!edge_accessor) return t.commit(), false;
 
         // print edge type and properties
@@ -99,11 +97,11 @@ auto load_queries(Db &db)
 
         auto from = edge_accessor.from();
         cout << "FROM:" << endl;
-        cout_properties(from->find(t)->data.props);
+        cout_properties(from.record->data.props);
 
         auto to = edge_accessor.to();
         cout << "TO:" << endl;
-        cout_properties(to->find(t)->data.props);
+        cout_properties(to.record->data.props);
 
         t.commit();
 
@@ -111,9 +109,9 @@ auto load_queries(Db &db)
     };
 
     auto update_node = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
+        DbAccessor t(db);
 
-        auto v = db.graph.vertices.find(t, args[0]->as<Int32>().value);
+        auto v = t.vertex_find(args[0]->as<Int32>().value);
         if (!v) return t.commit(), false;
 
         v.property("name", args[1]);
@@ -127,18 +125,17 @@ auto load_queries(Db &db)
     // MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25,
     // weight: 70}]-(n2) RETURN r
     auto create_edge_v2 = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
-        auto n1 = db.graph.vertices.find(t, args[0]->as<Int64>().value);
+        DbAccessor t(db);
+        auto n1 = t.vertex_find(args[0]->as<Int64>().value);
         if (!n1) return t.commit(), false;
-        auto n2 = db.graph.vertices.find(t, args[1]->as<Int64>().value);
+        auto n2 = t.vertex_find(args[1]->as<Int64>().value);
         if (!n2) return t.commit(), false;
-        auto r = db.graph.edges.insert(t, n2.vlist, n1.vlist);
+        auto r = t.edge_insert(n2.vlist, n1.vlist);
         r.property("age", args[2]);
         r.property("weight", args[3]);
-        auto &IS = db.graph.edge_type_store.find_or_create("IS");
+        auto &IS = t.type_find_or_create("IS");
         r.edge_type(IS);
-        n2.vlist->update(t)->data.out.add(r.vlist);
-        n1.vlist->update(t)->data.in.add(r.vlist);
+
         t.commit();
         return true;
     };
@@ -146,11 +143,11 @@ auto load_queries(Db &db)
 
     // MATCH (n) RETURN n
     auto match_all_nodes = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
+        DbAccessor t(db);
 
-        auto vertices_accessor = db.graph.vertices.access();
+        auto vertices_accessor = t.vertex_access();
         for (auto &it : vertices_accessor) {
-            auto vertex = it.second.find(t);
+            auto vertex = it.second.find(*t);
             if (vertex == nullptr) continue;
             cout_properties(vertex->data.props);
         }
@@ -166,12 +163,11 @@ auto load_queries(Db &db)
 
     // MATCH (n:LABEL) RETURN n
     auto find_by_label = [&db](const properties_t &args) {
-        auto &t = db.tx_engine.begin();
+        DbAccessor t(db);
 
-        auto &label = db.graph.label_store.find_or_create("LABEL");
+        auto &label = t.label_find_or_create("LABEL");
 
-        auto &index_record_collection =
-            db.graph.vertices.find_label_index(label);
+        auto &index_record_collection = t.label_find_index(label);
         auto accessor = index_record_collection.access();
         cout << "VERTICES" << endl;
         for (auto &v : accessor) {
diff --git a/include/storage/edge_accessor.hpp b/include/storage/edge_accessor.hpp
index 192ce2884..b43612111 100644
--- a/include/storage/edge_accessor.hpp
+++ b/include/storage/edge_accessor.hpp
@@ -3,31 +3,27 @@
 #include "storage/edge.hpp"
 #include "storage/edge_record.hpp"
 #include "storage/record_accessor.hpp"
+#include "storage/vertex_accessor.hpp"
 #include "utils/assert.hpp"
 #include "utils/reference_wrapper.hpp"
 
 class Edges;
 
 // TODO: Edge, Db, Edge::Accessor
-class Edge::Accessor
-    : public RecordAccessor<Edge, Edges, Edge::Accessor, EdgeRecord>
+class Edge::Accessor : public RecordAccessor<Edge, Edge::Accessor, EdgeRecord>
 {
 public:
     using RecordAccessor::RecordAccessor;
 
-    void edge_type(edge_type_ref_t edge_type)
-    {
-        this->record->data.edge_type = &edge_type.get();
-    }
+    void edge_type(edge_type_ref_t edge_type);
 
-    edge_type_ref_t edge_type() const
-    {
-        runtime_assert(this->record->data.edge_type != nullptr,
-                       "EdgeType is null");
-        return edge_type_ref_t(*this->record->data.edge_type);
-    }
+    edge_type_ref_t edge_type() const;
 
-    auto from() const { return this->vlist->from(); }
+    Vertex::Accessor from() const;
 
-    auto to() const { return this->vlist->to(); }
+    Vertex::Accessor to() const;
+
+    VertexRecord *from_record() const;
+
+    VertexRecord *to_record() const;
 };
diff --git a/include/storage/edges.hpp b/include/storage/edges.hpp
index 85e2e1cdd..5cc00b670 100644
--- a/include/storage/edges.hpp
+++ b/include/storage/edges.hpp
@@ -8,8 +8,8 @@
 class Edges
 {
 public:
-    Edge::Accessor find(tx::Transaction &t, const Id &id);
-    Edge::Accessor insert(tx::Transaction &t, VertexRecord *from,
+    Edge::Accessor find(DbTransaction &t, const Id &id);
+    Edge::Accessor insert(DbTransaction &t, VertexRecord *from,
                           VertexRecord *to);
 
 private:
diff --git a/include/storage/record_accessor.hpp b/include/storage/record_accessor.hpp
index 327d43e27..bc65f4559 100644
--- a/include/storage/record_accessor.hpp
+++ b/include/storage/record_accessor.hpp
@@ -1,23 +1,29 @@
 #pragma once
 
+#include "database/db_transaction.hpp"
 #include "mvcc/version_list.hpp"
 #include "storage/model/properties/properties.hpp"
 #include "storage/model/properties/property.hpp"
 #include "transactions/transaction.hpp"
 
-template <class T, class Store, class Derived,
-          class vlist_t = mvcc::VersionList<T>>
+template <class T, class Derived, class vlist_t = mvcc::VersionList<T>>
 class RecordAccessor
 {
 public:
-    RecordAccessor() = default;
+    RecordAccessor(DbTransaction &db) : db(db){};
 
-    RecordAccessor(T *record, vlist_t *vlist, Store *store)
-        : record(record), vlist(vlist), store(store)
+    RecordAccessor(T *t, vlist_t *vlist, DbTransaction &db)
+        : record(t), vlist(vlist), db(db)
+    {
+        assert(record != nullptr);
+        assert(vlist != nullptr);
+    }
+
+    RecordAccessor(vlist_t *vlist, DbTransaction &db)
+        : record(vlist->find(db.trans)), vlist(vlist), db(db)
     {
         assert(record != nullptr);
         assert(vlist != nullptr);
-        assert(store != nullptr);
     }
 
     bool empty() const { return record == nullptr; }
@@ -28,18 +34,18 @@ public:
         return vlist->id;
     }
 
-    Derived update(tx::Transaction &t) const
+    Derived update() const
     {
         assert(!empty());
 
-        return Derived(vlist->update(t), vlist, store);
+        return Derived(vlist->update(db.trans), vlist, db);
     }
 
-    bool remove(tx::Transaction &t) const
+    bool remove() const
     {
         assert(!empty());
 
-        return vlist->remove(record, t);
+        return vlist->remove(record, db.trans);
     }
 
     const Property &property(const std::string &key) const
@@ -65,5 +71,5 @@ public:
     // protected:
     T *const record{nullptr};
     vlist_t *const vlist{nullptr};
-    Store *const store{nullptr};
+    DbTransaction &db;
 };
diff --git a/include/storage/vertex_accessor.hpp b/include/storage/vertex_accessor.hpp
index 6c02f2595..2d32b1f88 100644
--- a/include/storage/vertex_accessor.hpp
+++ b/include/storage/vertex_accessor.hpp
@@ -5,8 +5,7 @@
 
 class Vertices;
 
-class Vertex::Accessor
-    : public RecordAccessor<Vertex, Vertices, Vertex::Accessor>
+class Vertex::Accessor : public RecordAccessor<Vertex, Vertex::Accessor>
 {
 public:
     using RecordAccessor::RecordAccessor;
@@ -21,5 +20,5 @@ public:
 
     bool has_label(const Label &label) const;
 
-    const std::set<label_ref_t>& labels() const;
+    const std::set<label_ref_t> &labels() const;
 };
diff --git a/include/storage/vertices.hpp b/include/storage/vertices.hpp
index 9b4909ebe..6f668514c 100644
--- a/include/storage/vertices.hpp
+++ b/include/storage/vertices.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "data_structures/concurrent/concurrent_map.hpp"
+#include "database/db_transaction.hpp"
 #include "storage/common.hpp"
 #include "storage/indexes/index.hpp"
 #include "storage/indexes/index_record_collection.hpp"
@@ -13,17 +14,17 @@ public:
 
     vertices_t::Accessor access();
 
-    const Vertex::Accessor find(tx::Transaction &t, const Id &id);
+    const Vertex::Accessor find(DbTransaction &t, const Id &id);
 
-    const Vertex::Accessor first(tx::Transaction &t);
+    const Vertex::Accessor first(DbTransaction &t);
 
-    Vertex::Accessor insert(tx::Transaction &t);
+    Vertex::Accessor insert(DbTransaction &t);
 
     void update_label_index(const Label &label,
                             VertexIndexRecord &&index_record);
 
-    VertexIndexRecordCollection& find_label_index(const Label& label);
-    
+    VertexIndexRecordCollection &find_label_index(const Label &label);
+
 private:
     vertices_t vertices;
     Index<label_ref_t, VertexIndexRecordCollection> label_index;
diff --git a/poc/astar.cpp b/poc/astar.cpp
index f30f1664d..1b564c02c 100644
--- a/poc/astar.cpp
+++ b/poc/astar.cpp
@@ -10,6 +10,7 @@
 
 #include "data_structures/map/rh_hashmap.hpp"
 #include "database/db.hpp"
+#include "database/db_accessor.hpp"
 
 using namespace std;
 
@@ -92,20 +93,20 @@ double calc_heuristic_cost_dummy(Edge *edge, Vertex *vertex)
     return 1 - vertex->data.props.at("score").as<Double>().value;
 }
 
-typedef bool (*EdgeFilter)(tx::Transaction &t, EdgeRecord *, Node *before);
-typedef bool (*VertexFilter)(tx::Transaction &t, Vertex *, Node *before);
+typedef bool (*EdgeFilter)(DbAccessor &t, EdgeRecord *, Node *before);
+typedef bool (*VertexFilter)(DbAccessor &t, Vertex *, Node *before);
 
-bool edge_filter_dummy(tx::Transaction &t, EdgeRecord *e, Node *before)
+bool edge_filter_dummy(DbAccessor &t, EdgeRecord *e, Node *before)
 {
     return true;
 }
 
-bool vertex_filter_dummy(tx::Transaction &t, Vertex *v, Node *before)
+bool vertex_filter_dummy(DbAccessor &t, Vertex *v, Node *before)
 {
     return true;
 }
 
-bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
+bool vertex_filter_contained_dummy(DbAccessor &t, Vertex *v, Node *before)
 {
     bool found;
     do {
@@ -115,7 +116,7 @@ bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
             return true;
         }
         for (auto edge : before->vertex->data.out) {
-            Vertex *e_v = edge->to()->find(t);
+            Vertex *e_v = edge->to()->find(*t);
             if (e_v == v) {
                 found = true;
                 break;
@@ -125,7 +126,7 @@ bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
     return false;
 }
 
-bool vertex_filter_contained(tx::Transaction &t, Vertex *v, Node *before)
+bool vertex_filter_contained(DbAccessor &t, Vertex *v, Node *before)
 {
     bool found;
     do {
@@ -146,14 +147,14 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
             double (*calc_heuristic_cost)(Edge *edge, Vertex *vertex),
             int limit)
 {
-    auto &t = db.tx_engine.begin();
+    DbAccessor t(db);
     RhHashMap<VertexRecord *, Node> visited;
 
     auto cmp = [](Node *left, Node *right) { return left->cost > right->cost; };
     std::priority_queue<Node *, std::vector<Node *>, decltype(cmp)> queue(cmp);
 
-    auto start_vr = db.graph.vertices.find(t, sys_id_start).vlist;
-    Node *start = new Node(start_vr->find(t), start_vr, 0);
+    auto start_vr = t.vertex_find(sys_id_start).vlist;
+    Node *start = new Node(start_vr->find(*t), start_vr, 0);
     queue.push(start);
     int count = 0;
     do {
@@ -175,11 +176,12 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
 
         for (auto edge : now->vertex->data.out) {
             if (e_filter[now->depth](t, edge, now)) {
-                Vertex *v = edge->to()->find(t);
+                Vertex *v = edge->to()->find(*t);
                 if (v_filter[now->depth](t, v, now)) {
                     Node *n = new Node(
                         v, edge->to(),
-                        now->cost + calc_heuristic_cost(edge->find(t), v), now);
+                        now->cost + calc_heuristic_cost(edge->find(*t), v),
+                        now);
                     queue.push(n);
                 }
             }
@@ -207,7 +209,7 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
 int main()
 {
     Db db;
-    load_csv(db, "neo4j_nodes_export_2000.csv", "neo4j_edges_export_2000.csv");
+    load_csv(db, "graph_nodes_export.csv", "graph_edges_export.csv");
     //
     // load_graph_dummy(db);
     //
@@ -266,7 +268,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
 
     std::string line;
 
-    auto &t = db.tx_engine.begin();
+    DbAccessor t(db);
     int max_score = 1000000;
 
     // VERTEX import
@@ -276,7 +278,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
             start_vertex_id = id;
         }
 
-        auto vertex_accessor = db.graph.vertices.insert(t);
+        auto vertex_accessor = t.vertex_insert();
         vertex_accessor.property("id", std::make_shared<Int32>(id));
         vertex_accessor.property("garment_id", std::make_shared<Int32>(gar_id));
         vertex_accessor.property("garment_category_id",
@@ -286,7 +288,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
             "score", std::make_shared<Double>((std::rand() % max_score) /
                                               (max_score + 0.0)));
         for (auto l_name : labels) {
-            auto &label = db.graph.label_store.find_or_create(l_name);
+            auto &label = t.label_find_or_create(l_name);
             vertex_accessor.add_label(label);
         }
         return vertex_accessor.id();
@@ -309,7 +311,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
                     stoi(splited[splited.size() - 1]));
 
         assert(va.size() == (uint64_t)id);
-        va.push_back(db.graph.vertices.find(t, id));
+        va.push_back(t.vertex_find(id));
     }
 
     // EDGE IMPORT
@@ -318,12 +320,9 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
 
         auto v2 = va[to - start_vertex_id];
 
-        auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
+        auto edge_accessor = t.edge_insert(v1.vlist, v2.vlist);
 
-        v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
-        v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
-
-        auto &edge_type = db.graph.edge_type_store.find_or_create(type);
+        auto &edge_type = t.type_find_or_create(type);
         edge_accessor.edge_type(edge_type);
     };
 
@@ -343,9 +342,9 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
 
 void load_graph_dummy(Db &db)
 {
-    auto &t = db.tx_engine.begin();
+    DbAccessor t(db);
     auto v = [&](auto id, auto score) {
-        auto vertex_accessor = db.graph.vertices.insert(t);
+        auto vertex_accessor = t.vertex_insert();
         vertex_accessor.property("id", std::make_shared<Int32>(id));
         vertex_accessor.property("score", std::make_shared<Double>(score));
         return vertex_accessor.id();
@@ -356,15 +355,13 @@ void load_graph_dummy(Db &db)
     };
 
     auto e = [&](auto from, auto type, auto to) {
-        auto v1 = db.graph.vertices.find(t, va[from]);
+        auto v1 = t.vertex_find(va[from]);
 
-        auto v2 = db.graph.vertices.find(t, va[to]);
+        auto v2 = t.vertex_find(va[to]);
 
-        auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
-        v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
-        v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
+        auto edge_accessor = t.edge_insert(v1.vlist, v2.vlist);
 
-        auto &edge_type = db.graph.edge_type_store.find_or_create(type);
+        auto &edge_type = t.type_find_or_create(type);
         edge_accessor.edge_type(edge_type);
     };
 
diff --git a/src/cypher/tokenizer/cypher_lexer.hpp b/src/cypher/tokenizer/cypher_lexer.hpp
index 42b4783ee..ed83cddfc 100644
--- a/src/cypher/tokenizer/cypher_lexer.hpp
+++ b/src/cypher/tokenizer/cypher_lexer.hpp
@@ -73,6 +73,6 @@ public:
 
         build();
     }
-    CypherLexer(CypherLexer& other) = delete;
-    CypherLexer(CypherLexer&& other) = default;
+    CypherLexer(CypherLexer &other) = delete;
+    CypherLexer(CypherLexer &&other) = default;
 };
diff --git a/src/database/db.cpp b/src/database/db.cpp
new file mode 100644
index 000000000..9ceb50a77
--- /dev/null
+++ b/src/database/db.cpp
@@ -0,0 +1,6 @@
+#include "database/db.hpp"
+
+Db::Db() = default;
+Db::Db(const std::string &name) : name_(name) {}
+
+std::string &Db::name() { return name_; }
diff --git a/src/database/db_accessor.cpp b/src/database/db_accessor.cpp
new file mode 100644
index 000000000..588e10f82
--- /dev/null
+++ b/src/database/db_accessor.cpp
@@ -0,0 +1,77 @@
+#include "database/db_accessor.hpp"
+
+DbAccessor::DbAccessor(Db &db) : db(DbTransaction(db, db.tx_engine.begin())) {}
+
+// VERTEX METHODS
+Vertices::vertices_t::Accessor DbAccessor::vertex_access()
+{
+    return this->db.db.graph.vertices.access();
+}
+
+const Vertex::Accessor DbAccessor::vertex_find(const Id &id)
+{
+    return this->db.db.graph.vertices.find(db, id);
+}
+
+const Vertex::Accessor DbAccessor::vertex_first()
+{
+    return this->db.db.graph.vertices.first(db);
+}
+
+Vertex::Accessor DbAccessor::vertex_insert()
+{
+    return this->db.db.graph.vertices.insert(db);
+}
+
+// EDGE METHODS
+
+Edge::Accessor DbAccessor::edge_find(const Id &id)
+{
+    return db.db.graph.edges.find(db, id);
+}
+
+Edge::Accessor DbAccessor::edge_insert(VertexRecord *from, VertexRecord *to)
+{
+    auto edge_accessor = db.db.graph.edges.insert(db, from, to);
+    from->update(db.trans)->data.out.add(edge_accessor.vlist);
+    to->update(db.trans)->data.in.add(edge_accessor.vlist);
+    return edge_accessor;
+}
+
+// LABEL METHODS
+const Label &DbAccessor::label_find_or_create(const std::string &name)
+{
+    return db.db.graph.label_store.find_or_create(
+        std::forward<const std::string &>(name));
+}
+
+bool DbAccessor::label_contains(const std::string &name)
+{
+    return db.db.graph.label_store.contains(
+        std::forward<const std::string &>(name));
+}
+
+VertexIndexRecordCollection &DbAccessor::label_find_index(const Label &label)
+{
+    return db.db.graph.vertices.find_label_index(label);
+}
+
+// TYPE METHODS
+const EdgeType &DbAccessor::type_find_or_create(const std::string &name)
+{
+    return db.db.graph.edge_type_store.find_or_create(
+        std::forward<const std::string &>(name));
+}
+
+bool DbAccessor::type_contains(const std::string &name)
+{
+    return db.db.graph.edge_type_store.contains(
+        std::forward<const std::string &>(name));
+}
+
+// TRANSACTION METHODS
+void DbAccessor::commit() { db.trans.commit(); }
+void DbAccessor::abort() { db.trans.abort(); }
+
+// EASE OF USE METHODS
+tx::Transaction &DbAccessor::operator*() { return db.trans; }
diff --git a/src/database/db_transaction.cpp b/src/database/db_transaction.cpp
new file mode 100644
index 000000000..3760ce479
--- /dev/null
+++ b/src/database/db_transaction.cpp
@@ -0,0 +1,8 @@
+#include "database/db.hpp"
+#include "database/db_transaction.hpp"
+
+void DbTransaction::update_label_index(const Label &label,
+                                       VertexIndexRecord &&index_record)
+{
+    db.graph.vertices.update_label_index(label, std::move(index_record));
+}
diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp
new file mode 100644
index 000000000..396234850
--- /dev/null
+++ b/src/storage/edge_accessor.cpp
@@ -0,0 +1,29 @@
+#include "storage/edge_accessor.hpp"
+
+void Edge::Accessor::edge_type(edge_type_ref_t edge_type)
+{
+    this->record->data.edge_type = &edge_type.get();
+}
+
+edge_type_ref_t Edge::Accessor::edge_type() const
+{
+    runtime_assert(this->record->data.edge_type != nullptr, "EdgeType is null");
+    return edge_type_ref_t(*this->record->data.edge_type);
+}
+
+Vertex::Accessor Edge::Accessor::from() const
+{
+    return Vertex::Accessor(this->vlist->from(), this->db);
+}
+
+Vertex::Accessor Edge::Accessor::to() const
+{
+    return Vertex::Accessor(this->vlist->to(), this->db);
+}
+
+VertexRecord *Edge::Accessor::from_record() const
+{
+    return this->vlist->from();
+}
+
+VertexRecord *Edge::Accessor::to_record() const { return this->vlist->to(); }
diff --git a/src/storage/edges.cpp b/src/storage/edges.cpp
index 22a3d4810..b4dc90fb7 100644
--- a/src/storage/edges.cpp
+++ b/src/storage/edges.cpp
@@ -1,21 +1,21 @@
 #include "storage/edges.hpp"
 
-Edge::Accessor Edges::find(tx::Transaction &t, const Id &id)
+Edge::Accessor Edges::find(DbTransaction &t, const Id &id)
 {
     auto edges_accessor = edges.access();
     auto edges_iterator = edges_accessor.find(id);
 
-    if (edges_iterator == edges_accessor.end()) return Edge::Accessor();
+    if (edges_iterator == edges_accessor.end()) return Edge::Accessor(t);
 
     // find edge
-    auto edge = edges_iterator->second.find(t);
+    auto edge = edges_iterator->second.find(t.trans);
 
-    if (edge == nullptr) return Edge::Accessor();
+    if (edge == nullptr) return Edge::Accessor(t);
 
-    return Edge::Accessor(edge, &edges_iterator->second, this);
+    return Edge::Accessor(edge, &edges_iterator->second, t);
 }
 
-Edge::Accessor Edges::insert(tx::Transaction &t, VertexRecord *from,
+Edge::Accessor Edges::insert(DbTransaction &t, VertexRecord *from,
                              VertexRecord *to)
 {
     // get next vertex id
@@ -30,7 +30,7 @@ Edge::Accessor Edges::insert(tx::Transaction &t, VertexRecord *from,
 
     // create new vertex
     auto inserted_edge_record = result.first;
-    auto edge = inserted_edge_record->second.insert(t);
+    auto edge = inserted_edge_record->second.insert(t.trans);
 
-    return Edge::Accessor(edge, &inserted_edge_record->second, this);
+    return Edge::Accessor(edge, &inserted_edge_record->second, t);
 }
diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp
index 380f30495..122ca7381 100644
--- a/src/storage/vertex_accessor.cpp
+++ b/src/storage/vertex_accessor.cpp
@@ -1,5 +1,5 @@
+#include "database/db.hpp"
 #include "storage/vertex_accessor.hpp"
-
 #include "storage/vertices.hpp"
 
 size_t Vertex::Accessor::out_degree() const
@@ -12,10 +12,7 @@ size_t Vertex::Accessor::in_degree() const
     return this->record->data.in.degree();
 }
 
-size_t Vertex::Accessor::degree() const
-{
-    return in_degree() + out_degree();
-}
+size_t Vertex::Accessor::degree() const { return in_degree() + out_degree(); }
 
 void Vertex::Accessor::add_label(const Label &label)
 {
@@ -23,8 +20,8 @@ void Vertex::Accessor::add_label(const Label &label)
     this->record->data.labels.add(label);
 
     // update index
-    this->store->update_label_index(
-        label, VertexIndexRecord(this->record, this->vlist));
+    this->db.update_label_index(label,
+                                VertexIndexRecord(this->record, this->vlist));
 }
 
 bool Vertex::Accessor::has_label(const Label &label) const
@@ -32,7 +29,7 @@ bool Vertex::Accessor::has_label(const Label &label) const
     return this->record->data.labels.has(label);
 }
 
-const std::set<label_ref_t>& Vertex::Accessor::labels() const
+const std::set<label_ref_t> &Vertex::Accessor::labels() const
 {
     return this->record->data.labels();
 }
diff --git a/src/storage/vertices.cpp b/src/storage/vertices.cpp
index ff94cb7dc..30634f67a 100644
--- a/src/storage/vertices.cpp
+++ b/src/storage/vertices.cpp
@@ -1,41 +1,40 @@
 #include "storage/vertices.hpp"
 
-Vertices::vertices_t::Accessor Vertices::access()
-{
-    return vertices.access();
-}
+Vertices::vertices_t::Accessor Vertices::access() { return vertices.access(); }
 
-const Vertex::Accessor Vertices::find(tx::Transaction &t, const Id &id)
+const Vertex::Accessor Vertices::find(DbTransaction &t, const Id &id)
 {
     auto vertices_accessor = vertices.access();
     auto vertices_iterator = vertices_accessor.find(id);
 
-    if (vertices_iterator == vertices_accessor.end()) return Vertex::Accessor();
+    if (vertices_iterator == vertices_accessor.end())
+        return Vertex::Accessor(t);
 
     // find vertex
-    auto vertex = vertices_iterator->second.find(t);
+    auto vertex = vertices_iterator->second.find(t.trans);
 
-    if (vertex == nullptr) return Vertex::Accessor();
+    if (vertex == nullptr) return Vertex::Accessor(t);
 
-    return Vertex::Accessor(vertex, &vertices_iterator->second, this);
+    return Vertex::Accessor(vertex, &vertices_iterator->second, t);
 }
 
 // TODO
-const Vertex::Accessor Vertices::first(tx::Transaction &t)
+const Vertex::Accessor Vertices::first(DbTransaction &t)
 {
     auto vertices_accessor = vertices.access();
     auto vertices_iterator = vertices_accessor.begin();
 
-    if (vertices_iterator == vertices_accessor.end()) return Vertex::Accessor();
+    if (vertices_iterator == vertices_accessor.end())
+        return Vertex::Accessor(t);
 
-    auto vertex = vertices_iterator->second.find(t);
+    auto vertex = vertices_iterator->second.find(t.trans);
 
-    if (vertex == nullptr) return Vertex::Accessor();
+    if (vertex == nullptr) return Vertex::Accessor(t);
 
-    return Vertex::Accessor(vertex, &vertices_iterator->second, this);
+    return Vertex::Accessor(vertex, &vertices_iterator->second, t);
 }
 
-Vertex::Accessor Vertices::insert(tx::Transaction &t)
+Vertex::Accessor Vertices::insert(DbTransaction &t)
 {
     // get next vertex id
     auto next = counter.next();
@@ -50,9 +49,9 @@ Vertex::Accessor Vertices::insert(tx::Transaction &t)
 
     // create new vertex
     auto inserted_vertex_record = result.first;
-    auto vertex = inserted_vertex_record->second.insert(t);
+    auto vertex = inserted_vertex_record->second.insert(t.trans);
 
-    return Vertex::Accessor(vertex, &inserted_vertex_record->second, this);
+    return Vertex::Accessor(vertex, &inserted_vertex_record->second, t);
 }
 
 void Vertices::update_label_index(const Label &label,