From d31e96535e3f41c36646f375680d7a4efc5772b2 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Wed, 3 Jul 2013 11:59:08 +0200
Subject: Test MySQL sub-second precision support

---
 mysql/types/driver.cxx | 29 +++++++++++++++++++++++++++++
 mysql/types/test.hxx   | 27 ++++++++++++++++++++++++---
 mysql/types/traits.hxx |  3 ++-
 3 files changed, 55 insertions(+), 4 deletions(-)

(limited to 'mysql')

diff --git a/mysql/types/driver.cxx b/mysql/types/driver.cxx
index 07487a2..12610d8 100644
--- a/mysql/types/driver.cxx
+++ b/mysql/types/driver.cxx
@@ -28,6 +28,16 @@ main (int argc, char* argv[])
   {
     auto_ptr<database> db (create_specific_database<database> (argc, argv));
 
+    mysql_version v;
+    {
+      transaction t (db->begin ());
+      db->query<mysql_version> ().begin ().load (v);
+      t.commit ();
+    }
+
+    //cerr << "MySQL " << v.major << '.' << v.minor << '.' << v.release
+    //     << " protocol " << v.protocol << endl;
+
     object o (1);
 
     o.bool_ = true;
@@ -53,6 +63,25 @@ main (int argc, char* argv[])
     o.timestamp_ = date_time (false, 2010, 8, 29, 12, 26, 59);
     o.year_ = 2010;
 
+    // If we are running against MySQL 5.6.4 or later, add fractional
+    // seconds and also alter the table to allow sub-second precision.
+    //
+    if (v.major > 5 ||
+        (v.major == 5 && (v.minor > 6 ||
+                          (v.minor == 6 && v.release >= 4))))
+    {
+      o.time_.microseconds = 123456;
+      o.date_time_.microseconds = 234567;
+      o.timestamp_.microseconds = 345678;
+
+      transaction t (db->begin ());
+      db->execute ("ALTER TABLE `mysql_types_object`"           \
+                   "  MODIFY COLUMN `time` TIME(6),"            \
+                   "  MODIFY COLUMN `date_time` DATETIME(6),"   \
+                   "  MODIFY COLUMN `timestamp` TIMESTAMP(6)");
+      t.commit ();
+    }
+
     string short_str (128, 's');
     string medium_str (250, 'm');
     string long_str (2040, 'l');
diff --git a/mysql/types/test.hxx b/mysql/types/test.hxx
index 73160c2..c46175d 100644
--- a/mysql/types/test.hxx
+++ b/mysql/types/test.hxx
@@ -27,14 +27,16 @@ struct date_time
              unsigned int d,
              unsigned int h,
              unsigned int min,
-             unsigned int sec)
+             unsigned int sec,
+             unsigned int msec = 0)
       : negative (n),
         year (y),
         month (m),
         day (d),
         hour (h),
         minute (min),
-        second (sec)
+        second (sec),
+        microseconds (msec)
   {
   }
 
@@ -48,7 +50,8 @@ struct date_time
       day == y.day &&
       hour == y.hour &&
       minute == y.minute &&
-      second == y.second;
+      second == y.second &&
+      microseconds == y.microseconds;
   }
 
   bool negative;
@@ -58,6 +61,7 @@ struct date_time
   unsigned int hour;
   unsigned int minute;
   unsigned int second;
+  unsigned int microseconds;
 };
 
 struct bitfield
@@ -305,4 +309,21 @@ struct char_array
   }
 };
 
+// MySQL server version view.
+//
+#pragma db view query(                                                  \
+  "SELECT "                                                             \
+  "CAST(SUBSTRING_INDEX(@@version, '.', 1) AS UNSIGNED),"               \
+  "CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(@@version, '.', 2), '.', -1) AS UNSIGNED)," \
+  "CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(@@version, '-', 1), '.', -1) AS UNSIGNED)," \
+  "@@protocol_version")
+struct mysql_version
+{
+  unsigned int major;
+  unsigned int minor;
+  unsigned int release;
+
+  unsigned int protocol;
+};
+
 #endif // TEST_HXX
diff --git a/mysql/types/traits.hxx b/mysql/types/traits.hxx
index f1d98b7..53a130c 100644
--- a/mysql/types/traits.hxx
+++ b/mysql/types/traits.hxx
@@ -35,6 +35,7 @@ namespace odb
           v.hour = i.hour;
           v.minute = i.minute;
           v.second = i.second;
+          v.microseconds = static_cast<unsigned int> (i.second_part);
         }
         else
           v = date_time ();
@@ -51,7 +52,7 @@ namespace odb
         i.hour = v.hour;
         i.minute = v.minute;
         i.second = v.second;
-        i.second_part = 0;
+        i.second_part = v.microseconds;
       }
     };
 
-- 
cgit v1.1