From 2c3dcfeee4fd2adb5a7dbd9af1c8ee02d4664d39 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Thu, 5 Sep 2013 13:02:10 +0200
Subject: Versioned section support

---
 evolution/soft-delete/driver.cxx | 442 +++++++++++++++++++++++++++++++++++++++
 evolution/soft-delete/model.hxx  |  91 ++++++++
 2 files changed, 533 insertions(+)

(limited to 'evolution')

diff --git a/evolution/soft-delete/driver.cxx b/evolution/soft-delete/driver.cxx
index d0debce..b81cca0 100644
--- a/evolution/soft-delete/driver.cxx
+++ b/evolution/soft-delete/driver.cxx
@@ -120,6 +120,40 @@ main (int argc, char* argv[])
           }
         }
 
+        // Test soft-deleted section member.
+        //
+        {
+          using namespace test7;
+
+          object o (1);
+          o.str = "abc";
+          o.num = 123;
+          o.vec.push_back (123);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            t.commit ();
+          }
+        }
+
+        // Test soft-deleted members of a section.
+        //
+        {
+          using namespace test8;
+
+          object o (1);
+          o.str = "abc";
+          o.num = 123;
+          o.vec.push_back (123);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            t.commit ();
+          }
+        }
+
 #endif // DATABASE_SQLITE
 
         // Test soft-deleted container member in a non-versioned object.
@@ -138,6 +172,22 @@ main (int argc, char* argv[])
           }
         }
 
+        // Test soft-deleted container member in a non-versioned section.
+        //
+        {
+          using namespace test22;
+
+          object o (1);
+          o.num = 123;
+          o.vec.push_back (123);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            t.commit ();
+          }
+        }
+
         break;
       }
     case 2:
@@ -291,6 +341,132 @@ main (int argc, char* argv[])
           }
         }
 
+        // Test soft-deleted section member.
+        //
+        {
+          using namespace test7;
+
+          // All the database operations should still include the deleted
+          // members.
+          //
+          {
+            transaction t (db->begin ());
+            auto_ptr<object> p (db->load<object> (1));
+            db->load (*p, p->s);
+            assert (p->str == "abc" && p->num == 123 && p->vec[0] == 123);
+            t.commit ();
+          }
+
+          {
+            typedef odb::query<object> query;
+            typedef odb::result<object> result;
+
+            transaction t (db->begin ());
+            result r (db->query<object> (query::str == "abc"));
+            result::iterator i (r.begin ());
+            assert (i != r.end ());
+            db->load (*i, i->s);
+            assert (i->str == "abc" && i->num == 123 && i->vec[0] == 123);
+            t.commit ();
+          }
+
+          object o (2);
+          o.str = "bcd";
+          o.num = 234;
+          o.vec.push_back (234);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "bcd" && p->num == 234 && p->vec[0] == 234);
+            t.commit ();
+          }
+
+          o.str += 'e';
+          o.num++;
+          o.vec.modify (0)++; // Automatically marks section as updated.
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "bcde" && p->num == 235 && p->vec[0] == 235);
+            t.commit ();
+          }
+
+          {
+            transaction t (db->begin ());
+            db->erase (o);
+            t.commit ();
+          }
+        }
+
+        // Test soft-deleted members of a section.
+        //
+        {
+          using namespace test8;
+
+          // All the database operations should still include the deleted
+          // members.
+          //
+          {
+            transaction t (db->begin ());
+            auto_ptr<object> p (db->load<object> (1));
+            db->load (*p, p->s);
+            assert (p->str == "abc" && p->num == 123 && p->vec[0] == 123);
+            t.commit ();
+          }
+
+          {
+            typedef odb::query<object> query;
+            typedef odb::result<object> result;
+
+            transaction t (db->begin ());
+            result r (db->query<object> (query::str == "abc"));
+            result::iterator i (r.begin ());
+            assert (i != r.end ());
+            db->load (*i, i->s);
+            assert (i->str == "abc" && i->num == 123 && i->vec[0] == 123);
+            t.commit ();
+          }
+
+          object o (2);
+          o.str = "bcd";
+          o.num = 234;
+          o.vec.push_back (234);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "bcd" && p->num == 234 && p->vec[0] == 234);
+            t.commit ();
+          }
+
+          o.str += 'e';
+          o.num++;
+          o.vec.modify (0)++; // Automatically marks section as updated.
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "bcde" && p->num == 235 && p->vec[0] == 235);
+            t.commit ();
+          }
+
+          {
+            transaction t (db->begin ());
+            db->erase (o);
+            t.commit ();
+          }
+        }
+
 #endif // DATABASE_SQLITE
 
         // Test soft-deleted container member in a non-versioned object.
@@ -349,6 +525,67 @@ main (int argc, char* argv[])
           }
         }
 
+        // Test soft-deleted container member in a non-versioned section.
+        //
+        {
+          using namespace test22;
+
+          // All the database operations should still include the deleted
+          // members.
+          //
+          {
+            transaction t (db->begin ());
+            auto_ptr<object> p (db->load<object> (1));
+            db->load (*p, p->s);
+            assert (p->num == 123 && p->vec[0] == 123);
+            t.commit ();
+          }
+
+          {
+            typedef odb::query<object> query;
+            typedef odb::result<object> result;
+
+            transaction t (db->begin ());
+            result r (db->query<object> (query::num == 123));
+            result::iterator i (r.begin ());
+            assert (i != r.end ());
+            db->load (*i, i->s);
+            assert (i->num == 123 && i->vec[0] == 123);
+            t.commit ();
+          }
+
+          object o (2);
+          o.num = 234;
+          o.vec.push_back (234);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->num == 234 && p->vec[0] == 234);
+            t.commit ();
+          }
+
+          o.num++;
+          o.vec.modify (0)++; // Automatically marks section as changed.
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->num == 235 && p->vec[0] == 235);
+            t.commit ();
+          }
+
+          {
+            transaction t (db->begin ());
+            db->erase (o);
+            t.commit ();
+          }
+        }
+
         if (embedded)
         {
           transaction t (db->begin ());
@@ -568,6 +805,139 @@ main (int argc, char* argv[])
           }
         }
 
+        // Test soft-deleted section member.
+        //
+        {
+          using namespace test7;
+
+          // Now none of the database operations should include the
+          // deleted members.
+          //
+          {
+            transaction t (db->begin ());
+            auto_ptr<object> p (db->load<object> (1));
+
+            try
+            {
+              db->load (*p, p->s); // No such column.
+              assert (false);
+            }
+            catch (const odb::exception&) {}
+
+            t.commit ();
+          }
+
+          object o (2);
+          o.str = "bcd";
+          o.num = 234;
+          o.vec.push_back (234);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            t.commit ();
+          }
+
+          o.str += 'e';
+          o.num++;
+          o.vec.modify (0)++;
+          o.s.change ();
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            t.commit ();
+          }
+
+          {
+            transaction t (db->begin ());
+            db->erase<object> (2);
+            t.commit ();
+          }
+        }
+
+        // Test soft-deleted members of a section.
+        //
+        {
+          using namespace test8;
+
+          // Now none of the database operations should include the
+          // deleted members.
+          //
+          {
+            transaction t (db->begin ());
+            auto_ptr<object> p (db->load<object> (1));
+            db->load (*p, p->s);
+            assert (p->str == "" && p->num == 123 && p->vec.empty ());
+            t.commit ();
+          }
+
+          {
+            typedef odb::query<object> query;
+            typedef odb::result<object> result;
+
+            transaction t (db->begin ());
+            result r (db->query<object> (query::num == 123));
+            result::iterator i (r.begin ());
+            assert (i != r.end ());
+            db->load (*i, i->s);
+            assert (i->str == "" && i->num == 123 && i->vec.empty ());
+
+            try
+            {
+              db->query<object> (query::str == "abc"); // No such column.
+              assert (false);
+            }
+            catch (const odb::exception&) {}
+
+            t.commit ();
+          }
+
+          object o (2);
+          o.str = "bcd";
+          o.num = 234;
+          o.vec.push_back (234);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "" && p->num == 234 && p->vec.empty ());
+            t.commit ();
+          }
+
+          o.str += 'e';
+          o.num++;
+          o.vec.modify (0)++; // No longer automatically marked as changed.
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "" && p->num == 234 && p->vec.empty ());
+            t.commit ();
+          }
+
+          o.s.change ();
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->str == "" && p->num == 235 && p->vec.empty ());
+            t.commit ();
+          }
+
+          {
+            transaction t (db->begin ());
+            db->erase<object> (2);
+            t.commit ();
+          }
+        }
+
 #endif // DATABASE_SQLITE
 
         // Test soft-deleted container member in a non-versioned object.
@@ -626,6 +996,78 @@ main (int argc, char* argv[])
           }
         }
 
+        // Test soft-deleted container member in a non-versioned section.
+        //
+        {
+          using namespace test22;
+
+          // Now none of the database operations should include the
+          // deleted members.
+          //
+          {
+            transaction t (db->begin ());
+            auto_ptr<object> p (db->load<object> (1));
+            db->load (*p, p->s);
+            assert (p->num == 123 && p->vec.empty ());
+            t.commit ();
+          }
+
+          {
+            typedef odb::query<object> query;
+            typedef odb::result<object> result;
+
+            transaction t (db->begin ());
+            result r (db->query<object> (query::num == 123));
+            result::iterator i (r.begin ());
+            assert (i != r.end ());
+            db->load (*i, i->s);
+            assert (i->num == 123 && i->vec.empty ());
+            t.commit ();
+          }
+
+          object o (2);
+          o.num = 234;
+          o.vec.push_back (234);
+
+          {
+            transaction t (db->begin ());
+            db->persist (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->num == 234 && p->vec.empty ());
+            t.commit ();
+          }
+
+          o.num++;
+          o.vec.modify (0)++; // No longer automatically marks as changed.
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->num == 234 && p->vec.empty ());
+            t.commit ();
+          }
+
+          o.s.change ();
+
+          {
+            transaction t (db->begin ());
+            db->update (o);
+            auto_ptr<object> p (db->load<object> (2));
+            db->load (*p, p->s);
+            assert (p->num == 235 && p->vec.empty ());
+            t.commit ();
+          }
+
+          {
+            transaction t (db->begin ());
+            db->erase<object> (2);
+            t.commit ();
+          }
+        }
+
         break;
       }
     default:
diff --git a/evolution/soft-delete/model.hxx b/evolution/soft-delete/model.hxx
index 6abdd39..5defcac 100644
--- a/evolution/soft-delete/model.hxx
+++ b/evolution/soft-delete/model.hxx
@@ -10,6 +10,7 @@
 
 #include <odb/core.hxx>
 #include <odb/vector.hxx>
+#include <odb/section.hxx>
 
 #include <common/config.hxx> // DATABASE_XXX
 
@@ -178,6 +179,68 @@ namespace MODEL_NAMESPACE(MODEL_VERSION)
 #endif
   }
 
+  // Test soft-deleted section member.
+  //
+  #pragma db namespace table("t7_")
+  namespace test7
+  {
+    #pragma db object
+    struct object
+    {
+      object (unsigned long id = 0): id_ (id) {}
+
+      #pragma db id
+      unsigned long id_;
+
+      #pragma db load(lazy) update(change)
+      odb::section s;
+
+      #pragma db section(s)
+      std::string str;
+
+      unsigned long num;
+
+      #pragma db section(s)
+      odb::vector<int> vec;
+    };
+
+#if MODEL_VERSION == 3
+    #pragma db member(object::s) deleted(3)
+#endif
+  }
+
+  // Test soft-deleted members of a section.
+  //
+  #pragma db namespace table("t8_")
+  namespace test8
+  {
+    #pragma db object
+    struct object
+    {
+      object (unsigned long id = 0): id_ (id) {}
+
+      #pragma db id
+      unsigned long id_;
+
+      #pragma db load(lazy) update(change)
+      odb::section s;
+
+      #pragma db section(s)
+      std::string str;
+
+      #pragma db section(s)
+      unsigned long num;
+
+      #pragma db section(s)
+      odb::vector<int> vec;
+    };
+
+#if MODEL_VERSION == 3
+    #pragma db member(object::str) deleted(3)
+    #pragma db member(object::vec) deleted(3)
+#endif
+  }
+
 #endif // DATABASE_SQLITE
 
   // Test soft-deleted container member in a non-versioned object.
@@ -201,6 +264,34 @@ namespace MODEL_NAMESPACE(MODEL_VERSION)
     #pragma db member(object::vec) deleted(3)
 #endif
   }
+
+  // Test soft-deleted container member in a non-versioned section.
+  //
+  #pragma db namespace table("t22_")
+  namespace test22
+  {
+    #pragma db object
+    struct object
+    {
+      object (unsigned long id = 0): id_ (id) {}
+
+      #pragma db id
+      unsigned long id_;
+
+      #pragma db load(lazy) update(change)
+      odb::section s;
+
+      #pragma db section(s)
+      unsigned long num;
+
+      #pragma db section(s)
+      odb::vector<int> vec;
+    };
+
+#if MODEL_VERSION == 3
+    #pragma db member(object::vec) deleted(3)
+#endif
+  }
 }
 
 #undef MODEL_NAMESPACE
-- 
cgit v1.1