From 7fb59e3beca03493426d0b4c4153d7e6b6d2f34b Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Mon, 2 Sep 2013 08:33:25 +0200
Subject: Support for versioning simple value in object

---
 odb/database.hxx         |  8 ++++++++
 odb/database.ixx         | 28 +++++++++++++++++++++++-----
 odb/polymorphic-info.hxx |  6 +++++-
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/odb/database.hxx b/odb/database.hxx
index ea5a37a..c7c4598 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -370,6 +370,13 @@ namespace odb
     schema_version_table (const std::string& table_name,
                           const std::string& schema_name);
 
+    // Schema version sequence number. It is incremented every time
+    // the schema version or migration flag is changed and can be
+    // used to detect version changes. The starting value is 1.
+    //
+    unsigned int
+    schema_version_sequence () const;
+
   protected:
     struct schema_version_info: schema_version_migration_type
     {
@@ -471,6 +478,7 @@ namespace odb
 
     std::string schema_version_table_;
     mutable schema_version_map schema_version_map_;
+    unsigned int schema_version_seq_;
   };
 }
 
diff --git a/odb/database.ixx b/odb/database.ixx
index 2fa57b3..3de5bbc 100644
--- a/odb/database.ixx
+++ b/odb/database.ixx
@@ -11,7 +11,7 @@ namespace odb
 {
   inline database::
   database (database_id id)
-      : id_ (id), tracer_ (0)
+      : id_ (id), tracer_ (0), schema_version_seq_ (1)
   {
   }
 
@@ -36,6 +36,10 @@ namespace odb
   inline const database::schema_version_migration_type& database::
   schema_version_migration (const std::string& name) const
   {
+    // Note that there is code that relies on the returned reference
+    // being valid until the version is changed or the database instance
+    // is destroyed.
+    //
     schema_version_map::const_iterator i (schema_version_map_.find (name));
     return i != schema_version_map_.end () && i->second.version != 0
       ? i->second
@@ -48,8 +52,12 @@ namespace odb
                             const std::string& name)
   {
     schema_version_info& svi (schema_version_map_[name]);
-    svi.version = v;
-    svi.migration = m;
+    if (svi.version != v || svi.migration != m)
+    {
+      svi.version = v;
+      svi.migration = m;
+      schema_version_seq_++;
+    }
   }
 
   inline void database::
@@ -57,8 +65,12 @@ namespace odb
                             const std::string& name)
   {
     schema_version_info& svi (schema_version_map_[name]);
-    svi.version = svm.version;
-    svi.migration = svm.migration;
+    if (svi.version != svm.version || svi.migration != svm.migration)
+    {
+      svi.version = svm.version;
+      svi.migration = svm.migration;
+      schema_version_seq_++;
+    }
   }
 
   inline void database::
@@ -73,6 +85,12 @@ namespace odb
     schema_version_map_[sname].version_table = tname;
   }
 
+  inline unsigned int database::
+  schema_version_sequence () const
+  {
+    return schema_version_seq_;
+  }
+
   inline connection_ptr database::
   connection ()
   {
diff --git a/odb/polymorphic-info.hxx b/odb/polymorphic-info.hxx
index 7762525..92dfa98 100644
--- a/odb/polymorphic-info.hxx
+++ b/odb/polymorphic-info.hxx
@@ -11,6 +11,7 @@
 #include <typeinfo>
 
 #include <odb/forward.hxx> // database, connection
+#include <odb/schema-version.hxx>
 #include <odb/traits.hxx>
 
 namespace odb
@@ -116,7 +117,10 @@ namespace odb
     typedef bool (*dispatch_function) (
       call_type, odb::database&, const root_type*, const void* arg);
     typedef void (*delayed_loader_function) (
-      odb::database&, const id_type&, root_type&);
+      odb::database&,
+      const id_type&,
+      root_type&,
+      const schema_version_migration*);
 
   public:
     polymorphic_concrete_info (const std::type_info& t,
-- 
cgit v1.1