From 4542b56c188b4ec2218df538497c41e1e08076e8 Mon Sep 17 00:00:00 2001
From: Kruno Tomola Fabro <krunotf@memgraph.io>
Date: Tue, 30 Aug 2016 02:32:31 +0100
Subject: [PATCH] tmp commit

---
 include/barrier/barrier.hpp               |  23 +++-
 include/barrier/trans.hpp                 |   8 +-
 include/database/db_accessor.hpp          |   8 ++
 include/query_engine/hardcode/queries.hpp | 134 ++++++++++++++++++----
 include/utils/iterator/filter.hpp         |  52 +++++++++
 include/utils/iterator/for_all.hpp        |  13 +++
 poc/profile.hpp                           |  13 ---
 src/barrier/barrier.cpp                   |  15 ++-
 8 files changed, 227 insertions(+), 39 deletions(-)
 create mode 100644 include/utils/iterator/filter.hpp

diff --git a/include/barrier/barrier.hpp b/include/barrier/barrier.hpp
index e201b9d61..748358c54 100644
--- a/include/barrier/barrier.hpp
+++ b/include/barrier/barrier.hpp
@@ -25,6 +25,7 @@ class EdgeIterator;
 
 // TYPED ITERATORS
 class VertexAccessIterator;
+class EdgeAccessIterator;
 class OutEdgesIterator;
 class InEdgesIterator;
 
@@ -247,6 +248,8 @@ public:
 
     VertexAccessor vertex_insert();
 
+    EdgeAccessIterator edge_access();
+
     Option<const EdgeAccessor> edge_find(const Id &id);
 
     EdgeAccessor edge_insert(VertexAccessor const &from,
@@ -309,6 +312,22 @@ public:
     Option<const VertexAccessor> next();
 };
 
+// TODO: Find reasons of such great size ant try to decrease it.
+class EdgeAccessIterator : private Sized<552, 8>
+{
+public:
+    template <class T>
+    EdgeAccessIterator(T &&d);
+
+    EdgeAccessIterator(const EdgeAccessIterator &other) = delete;
+    EdgeAccessIterator(EdgeAccessIterator &&other);
+    ~EdgeAccessIterator();
+    EdgeAccessIterator &operator=(const EdgeAccessIterator &other) = delete;
+    EdgeAccessIterator &operator=(EdgeAccessIterator &&other) = delete;
+
+    Option<const EdgeAccessor> next();
+};
+
 class OutEdgesIterator : private Sized<40, 8>
 {
 public:
@@ -442,10 +461,10 @@ public:
     void write_success_empty();
     void write_ignored();
     void write_fields(const std::vector<std::string> &fields);
-    void write_field(const std::string& field);
+    void write_field(const std::string &field);
     void write_list_header(size_t size);
     void write_record();
-    void write_meta(const std::string& type);
+    void write_meta(const std::string &type);
     void send();
     void chunk();
 };
diff --git a/include/barrier/trans.hpp b/include/barrier/trans.hpp
index af7c8ad76..2aa927d98 100644
--- a/include/barrier/trans.hpp
+++ b/include/barrier/trans.hpp
@@ -5,9 +5,9 @@
 // This is the place for imports from memgraph .hpp
 #include "communication/bolt/v1/serialization/bolt_serializer.hpp"
 #include "communication/bolt/v1/serialization/record_stream.hpp"
-#include "io/network/socket.hpp"
 #include "database/db.hpp"
 #include "database/db_accessor.hpp"
+#include "io/network/socket.hpp"
 #include "storage/edge_type/edge_type.hpp"
 #include "storage/edge_x_vertex.hpp"
 #include "storage/label/label.hpp"
@@ -126,6 +126,9 @@
 using vertex_access_iterator_t =
     decltype(((::DbAccessor *)(std::nullptr_t()))->vertex_access());
 
+using edge_access_iterator_t =
+    decltype(((::DbAccessor *)(std::nullptr_t()))->edge_access());
+
 using out_edge_iterator_t =
     decltype(((::VertexAccessor *)(std::nullptr_t()))->out());
 
@@ -160,6 +163,7 @@ TRANSFORM_REF(VertexIterator,
 TRANSFORM_REF(EdgeIterator,
               std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
 TRANSFORM_REF(VertexAccessIterator, vertex_access_iterator_t);
+TRANSFORM_REF(EdgeAccessIterator, edge_access_iterator_t);
 TRANSFORM_REF(OutEdgesIterator, out_edge_iterator_t);
 TRANSFORM_REF(InEdgesIterator, in_edge_iterator_t);
 
@@ -190,6 +194,8 @@ TRANSFORM_VALUE(VertexPropertyKey,
                 ::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
 TRANSFORM_VALUE_ONE(VertexAccessIterator, vertex_access_iterator_t);
 MOVE_CONSTRUCTOR_FORCED(VertexAccessIterator, vertex_access_iterator_t);
+TRANSFORM_VALUE_ONE(EdgeAccessIterator, edge_access_iterator_t);
+MOVE_CONSTRUCTOR_FORCED(EdgeAccessIterator, edge_access_iterator_t);
 TRANSFORM_VALUE_ONE(OutEdgesIterator, out_edge_iterator_t);
 MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t);
 TRANSFORM_VALUE_ONE(InEdgesIterator, in_edge_iterator_t);
diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp
index 8614a341a..8df93dfb8 100644
--- a/include/database/db_accessor.hpp
+++ b/include/database/db_accessor.hpp
@@ -69,6 +69,14 @@ public:
     VertexAccessor vertex_insert();
 
     // ******************* EDGE METHODS
+    auto edge_access()
+    {
+        return iter::make_map(
+            iter::make_iter(this->db_transaction.db.graph.edges.access()),
+            [&](auto e) -> auto {
+                return EdgeAccessor(&(e->second), db_transaction);
+            });
+    }
 
     Option<const EdgeAccessor> edge_find(const Id &id);
 
diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index f50d7c0c4..11b7bfa5a 100644
--- a/include/query_engine/hardcode/queries.hpp
+++ b/include/query_engine/hardcode/queries.hpp
@@ -20,8 +20,7 @@ auto load_queries(Db &db)
 
         auto vertex_accessor = t.vertex_insert();
         vertex_accessor.set(prop_key, args[0]);
-        t.commit();
-        return true;
+        return t.commit();
     };
     queries[11597417457737499503u] = create_node;
 
@@ -34,8 +33,7 @@ auto load_queries(Db &db)
         vertex_accessor.set(prop_key, args[0]);
         vertex_accessor.add_label(label);
         // cout_properties(vertex_accessor.properties());
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     auto create_account = [&db](const properties_t &args) {
@@ -53,8 +51,7 @@ auto load_queries(Db &db)
         vertex_accessor.set(prop_created, args[3]);
         vertex_accessor.add_label(label);
         // cout_properties(vertex_accessor.properties());
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     auto find_node_by_internal_id = [&db](const properties_t &args) {
@@ -71,8 +68,7 @@ auto load_queries(Db &db)
         for (auto label_ref : vertex_accessor.labels()) {
             // cout << label_ref.get() << endl;
         }
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     auto create_edge = [&db](const properties_t &args) {
@@ -89,13 +85,13 @@ auto load_queries(Db &db)
 
         edge_accessor.edge_type(edge_type);
 
-        t.commit();
+        bool ret = t.commit();
 
         // cout << edge_accessor.edge_type() << endl;
 
         // cout_properties(edge_accessor.properties());
 
-        return true;
+        return ret;
     };
 
     auto find_edge_by_internal_id = [&db](const properties_t &args) {
@@ -119,9 +115,7 @@ auto load_queries(Db &db)
         cout << "TO:" << endl;
         // cout_properties(to->data.props);
 
-        t.commit();
-
-        return true;
+        return t.commit();
     };
 
     auto update_node = [&db](const properties_t &args) {
@@ -135,9 +129,7 @@ auto load_queries(Db &db)
         v.set(prop_name, args[1]);
         // cout_properties(v.properties());
 
-        t.commit();
-
-        return true;
+        return t.commit();
     };
 
     // MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25,
@@ -158,8 +150,7 @@ auto load_queries(Db &db)
         auto &IS = t.type_find_or_create("IS");
         r.edge_type(IS);
 
-        t.commit();
-        return true;
+        return t.commit();
     };
 
     // MATCH (n) RETURN n
@@ -172,7 +163,7 @@ auto load_queries(Db &db)
             }
         });
 
-        return t.commit(), true;
+        return t.commit();
     };
 
     // MATCH (n:LABEL) RETURN n
@@ -186,9 +177,106 @@ auto load_queries(Db &db)
         iter::for_all(label.index().for_range(t),
                       [&](auto a) { cout << a.at(prop_key) << endl; });
 
-        return t.commit(), true;
+        return t.commit();
     };
 
+    // MATCH (n) DELETE n
+    auto match_all_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        iter::for_all(t.vertex_access(), [&](auto a) {
+            if (a.fill()) {
+                a.remove();
+            }
+        });
+
+        return t.commit();
+    };
+
+    // MATCH (n:LABEL) DELETE n
+    auto match_label_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &label = t.label_find_or_create("LABEL");
+
+        iter::for_all(label.index().for_range(t), [&](auto a) {
+            if (a.fill()) {
+                a.remove();
+            }
+        });
+
+        return t.commit();
+    };
+
+    // MATCH (n) WHERE ID(n) = id DELETE n
+    auto match_id_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto ov = t.vertex_find(args[0]->as<Int64>().value);
+        if (!option_fill(ov)) return t.commit(), false;
+
+        auto v = ov.take();
+        v.remove();
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r
+    auto match_edge_id_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto ov = t.edge_find(args[0]->as<Int64>().value);
+        if (!option_fill(ov)) return t.commit(), false;
+
+        auto v = ov.take();
+        v.remove();
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r]-() DELETE r
+    auto match_edge_all_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        iter::for_all(t.edge_access(), [&](auto a) {
+            if (a.fill()) {
+                a.remove();
+            }
+        });
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r:TYPE]-() DELETE r
+    auto match_edge_type_delete = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        auto &type = t.type_find_or_create("TYPE");
+
+        iter::for_all(type.index().for_range(t), [&](auto a) {
+            if (a.fill()) {
+                a.remove();
+            }
+        });
+
+        return t.commit();
+    };
+
+    // MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r
+    auto = [&db](const properties_t &args) {
+        DbAccessor t(db);
+
+        return t.commit();
+    };
+
+    // Blueprint:
+    // auto  = [&db](const properties_t &args) {
+    //     DbAccessor t(db);
+    //
+    //
+    //     return t.commit();
+    // };
+
     queries[15284086425088081497u] = match_all_nodes;
     queries[4857652843629217005u] = match_by_label;
     queries[15648836733456301916u] = create_edge_v2;
@@ -199,6 +287,12 @@ auto load_queries(Db &db)
     queries[11198568396549106428u] = find_node_by_internal_id;
     queries[8320600413058284114u] = find_edge_by_internal_id;
     queries[6813335159006269041u] = update_node;
+    queries[10506105811763742758u] = match_all_delete;
+    queries[13742779491897528506u] = match_label_delete;
+    queries[11349462498691305864u] = match_id_delete;
+    queries[6963549500479100885u] = match_edge_id_delete;
+    queries[14897166600223619735u] = match_edge_all_delete;
+    queries[16888549834923624215u] = match_edge_type_delete;
 
     return queries;
 }
diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp
new file mode 100644
index 000000000..ddbc45700
--- /dev/null
+++ b/include/utils/iterator/filter.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "utils/iterator/iterator_base.hpp"
+#include "utils/option.hpp"
+
+namespace iter
+{
+
+// Class which maps values returned by I iterator into value of type T with OP
+// function.
+// T - type of return value
+// I - iterator type
+// OP - type of mapper function
+template <class T, class I, class OP>
+class Map : public IteratorBase<T>
+{
+
+public:
+    Map() = delete;
+
+    // Map operation is designed to be used in chained calls which operate on a
+    // iterator. Map will in that usecase receive other iterator by value and
+    // std::move is a optimization for it.
+    Map(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
+
+    Map(Map &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
+
+    ~Map() final {}
+
+    Option<T> next() final
+    {
+        auto item = iter.next();
+        if (item.is_present()) {
+            return Option<T>(op(item.take()));
+        } else {
+            return Option<T>();
+        }
+    }
+
+private:
+    I iter;
+    OP op;
+};
+
+template <class I, class OP>
+auto make_map(I &&iter, OP &&op)
+{
+    // Compiler cant deduce type T. decltype is here to help with it.
+    return Map<decltype(op(iter.next().take())), I, OP>(std::move(iter),
+                                                        std::move(op));
+}
+}
diff --git a/include/utils/iterator/for_all.hpp b/include/utils/iterator/for_all.hpp
index 043f2c882..d68344aff 100644
--- a/include/utils/iterator/for_all.hpp
+++ b/include/utils/iterator/for_all.hpp
@@ -25,4 +25,17 @@ void for_all(std::unique_ptr<I> &&iter, C &&consumer)
         e = iter->next();
     }
 }
+
+template <class I, class C>
+void find(I iter, C &&consumer)
+{
+    auto e = iter.next();
+    while (e.is_present()) {
+
+        if (consumer(e.take())) {
+            return;
+        }
+        e = iter.next();
+    }
+}
 }
diff --git a/poc/profile.hpp b/poc/profile.hpp
index 9e4548f21..0dea2abca 100644
--- a/poc/profile.hpp
+++ b/poc/profile.hpp
@@ -115,19 +115,6 @@ void for_all_fill(I iter, C &&consumer)
     }
 }
 
-template <class I, class C>
-void find(I iter, C &&consumer)
-{
-    auto e = iter.next();
-    while (e.is_present()) {
-
-        if (consumer(e.take())) {
-            return;
-        }
-        e = iter.next();
-    }
-}
-
 template <class I, class C>
 void find_fill(I iter, C &&consumer)
 {
diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp
index 7031230bd..a2630d0a3 100644
--- a/src/barrier/barrier.cpp
+++ b/src/barrier/barrier.cpp
@@ -148,6 +148,8 @@ Option<const VertexAccessor> DbAccessor::vertex_find(const Id &id)
 
 VertexAccessor DbAccessor::vertex_insert() { return CALL(vertex_insert()); }
 
+EdgeAccessIterator DbAccessor::edge_access() { return CALL(edge_access()); }
+
 Option<const EdgeAccessor> DbAccessor::edge_find(const Id &id)
 {
     return HALF_CALL(edge_find(id)).map<const EdgeAccessor>();
@@ -467,6 +469,14 @@ Option<const VertexAccessor> VertexAccessIterator::next()
     return HALF_CALL(next()).map<const VertexAccessor>();
 }
 
+// ************************* EdgeAccessIterator
+DESTRUCTOR(EdgeAccessIterator, edge_access_iterator_t);
+
+Option<const EdgeAccessor> EdgeAccessIterator::next()
+{
+    return HALF_CALL(next()).map<const EdgeAccessor>();
+}
+
 // ************************* VertexPropertyKey
 DESTRUCTOR(VertexPropertyKey, PropertyFamilyKey);
 
@@ -596,7 +606,7 @@ void RecordStream<Stream>::write_fields(const std::vector<std::string> &fields)
 }
 
 template <class Stream>
-void RecordStream<Stream>::write_field(const std::string& field)
+void RecordStream<Stream>::write_field(const std::string &field)
 {
     HALF_CALL(write_field(field));
 }
@@ -614,7 +624,7 @@ void RecordStream<Stream>::write_record()
 }
 
 template <class Stream>
-void RecordStream<Stream>::write_meta(const std::string& type)
+void RecordStream<Stream>::write_meta(const std::string &type)
 {
     HALF_CALL(write_meta(type));
 }
@@ -632,7 +642,6 @@ void RecordStream<Stream>::chunk()
 }
 
 template class RecordStream<io::Socket>;
-
 }
 
 // **************************** ERROR EXAMPLES ****************************** //