From d13c76c39ddbedb4122f02e2c2bc168f1cb1cf20 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Thu, 2 Jul 2015 15:00:48 +0200
Subject: Test custom C++ type mapping for id, version members

---
 common/as/driver.cxx | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
 common/as/test.hxx   |  75 +++++++++++++++++++++++++++++-
 2 files changed, 200 insertions(+), 1 deletion(-)

diff --git a/common/as/driver.cxx b/common/as/driver.cxx
index 6305922..72ddb10 100644
--- a/common/as/driver.cxx
+++ b/common/as/driver.cxx
@@ -212,6 +212,132 @@ main (int argc, char* argv[])
         assert (*p2 == o2);
       }
     }
+
+    // Test id type mapping.
+    //
+    {
+      using namespace test4;
+
+      object o1 (123);
+      o1.v.push_back (1);
+      o1.v.push_back (2);
+      o1.v.push_back (3);
+
+      object o2 (234);
+      o2.v.push_back (3);
+      o2.v.push_back (2);
+      o2.v.push_back (1);
+
+      {
+        transaction t (db->begin ());
+        db->persist (o1);
+        db->persist (o2);
+        t.commit ();
+      }
+
+      {
+        transaction t (db->begin ());
+        auto_ptr<object> p1 (db->load<object> (o1.id));
+        auto_ptr<object> p2 (db->load<object> (o2.id));
+        t.commit ();
+
+        assert (*p1 == o1);
+        assert (*p2 == o2);
+      }
+
+      o1.i++;
+      o1.v.pop_back ();
+      o1.v.modify_front ()++;
+
+      o2.i--;
+      o2.v.clear ();
+      o2.v.push_back (4);
+
+      {
+        transaction t (db->begin ());
+        db->update (o1);
+        db->update (o2);
+        t.commit ();
+      }
+
+      {
+        transaction t (db->begin ());
+        auto_ptr<object> p1 (db->load<object> (o1.id));
+        auto_ptr<object> p2 (db->load<object> (o2.id));
+        t.commit ();
+
+        assert (*p1 == o1);
+        assert (*p2 == o2);
+      }
+    }
+
+    // Test version type mapping.
+    //
+    {
+      using namespace test5;
+
+      object o1 (100, 123);
+      object o2 (200, 234);
+
+      {
+        transaction t (db->begin ());
+        db->persist (o1);
+        db->persist (o2);
+        t.commit ();
+      }
+
+      {
+        transaction t (db->begin ());
+        auto_ptr<object> p1 (db->load<object> (o1.id));
+        auto_ptr<object> p2 (db->load<object> (o2.id));
+
+        assert (*p1 == o1);
+        assert (*p2 == o2);
+
+        p1->i--;
+        p2->i++;
+
+        db->update (*p1);
+        db->update (*p2);
+
+        t.commit ();
+      }
+
+      {
+        transaction t (db->begin ());
+
+        for (;;)
+        {
+          o1.i++;
+          o2.i--;
+
+          try
+          {
+
+            db->update (o1);
+            db->update (o2);
+            break;
+          }
+          catch (const odb::object_changed&)
+          {
+            db->reload (o1);
+            db->reload (o2);
+          }
+        }
+
+        t.commit ();
+      }
+
+      {
+        transaction t (db->begin ());
+        auto_ptr<object> p1 (db->load<object> (o1.id));
+        auto_ptr<object> p2 (db->load<object> (o2.id));
+        t.commit ();
+
+        assert (*p1 == o1);
+        assert (*p2 == o2);
+      }
+    }
   }
   catch (const odb::exception& e)
   {
diff --git a/common/as/test.hxx b/common/as/test.hxx
index 676f599..12822bb 100644
--- a/common/as/test.hxx
+++ b/common/as/test.hxx
@@ -193,6 +193,79 @@ namespace test3
   }
 }
 
-//@@ Test wrapped id and version. With container, obj-ptr.
+// Test id type mapping.
+//
+struct id_type
+{
+  typedef unsigned long value_type;
+  value_type value;
+
+  id_type (value_type v = 0): value (v) {}
+  operator value_type () const {return value;}
+};
+
+#pragma db map type(id_type) as(id_type::value_type)
+
+#pragma db namespace table("t4_")
+namespace test4
+{
+  #pragma db object
+  struct object
+  {
+    #pragma db id auto
+    id_type id;
+
+    int i;
+    odb::vector<int> v;
+
+    object () {}
+    object (int i_): i (i_) {}
+  };
+
+  inline bool
+  operator== (const object& x, const object y)
+  {
+    return x.id == y.id && x.i == y.i && x.v == y.v;
+  }
+}
+
+// Test version type mapping.
+//
+#pragma db namespace table("t5_")
+namespace test5
+{
+  struct version_type
+  {
+    typedef unsigned short value_type;
+    value_type value;
+
+    version_type (value_type v = 0): value (v) {}
+    operator value_type () const {return value;}
+    version_type& operator++ () {value++; return *this;}
+  };
+
+  #pragma db map type(version_type) as(id_type::value_type)
+
+  #pragma db object optimistic
+  struct object
+  {
+    #pragma db id
+    id_type id;
+
+    #pragma db version
+    version_type v;
+
+    int i;
+
+    object () {}
+    object (id_type id_, int i_): id (id_), i (i_) {}
+  };
+
+  inline bool
+  operator== (const object& x, const object y)
+  {
+    return x.id == y.id && x.v == y.v && x.i == y.i;
+  }
+}
 
 #endif // TEST_HXX
-- 
cgit v1.1