From 8e1f9ec9b0b3346d65d20e791391bb3a9594a256 Mon Sep 17 00:00:00 2001
From: Thomas Braun <thomas.braun@byte-physics.de>
Date: Sun, 27 Oct 2024 11:29:44 +0100
Subject: [PATCH] Fix timestamp columns in Mariadb 10.11 and newer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This problem appears in MariaDb 10.11 since default value of
explicit_defaults_for_timestamp changed from OFF to ON, setting it to
OFF (set global explicit_defaults_for_timestamp=OFF;) make the
create_db_tables.sql.in work properly.

Initial patch by Santiago Ruano Rincón with refinements by Graziano
Scalamera.

Upgrade script and tests by the author.

Origin: https://gitlab.com/tango-controls/TangoDatabase/-/merge_requests/95
---
 configure/CMakeLists.txt           |  1 +
 create_db_tables.sql.in            | 14 +++++++-------
 test/test.cpp                      | 27 +++++++++++++++++++++++++++
 update_db_from_5.23_to_5.24.sql.in | 11 +++++++++++
 4 files changed, 46 insertions(+), 7 deletions(-)
 create mode 100644 update_db_from_5.23_to_5.24.sql.in

diff --git a/cppserver/database/configure/CMakeLists.txt b/cppserver/database/configure/CMakeLists.txt
index 500139d..897d0c8 100644
--- a/cppserver/database/configure/CMakeLists.txt
+++ b/cppserver/database/configure/CMakeLists.txt
@@ -65,6 +65,7 @@ set(DB_SCRIPTS create_db.sql
                update_db_from_7_to_9.3.4.sql
                update_db_from_8_to_9.3.4.sql
                update_db_from_9.2.5_to_9.3.4.sql
+               update_db_from_5.23_to_5.24.sql
                update_db.sql)
 
 if (NOT WIN32)
diff --git a/cppserver/database/create_db_tables.sql.in b/cppserver/database/create_db_tables.sql.in
index c786937..cc38054 100644
--- a/cppserver/database/create_db_tables.sql.in
+++ b/cppserver/database/create_db_tables.sql.in
@@ -254,7 +254,7 @@ CREATE TABLE IF NOT EXISTS object_history_id (
 
 CREATE TABLE IF NOT EXISTS property_hist (
   id bigint unsigned NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   object varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
   count int(11) NOT NULL default '0',
@@ -265,7 +265,7 @@ CREATE TABLE IF NOT EXISTS property_hist (
 
 CREATE TABLE IF NOT EXISTS property_device_hist (
   id bigint unsigned NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   device varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
   count int(11) NOT NULL default '0',
@@ -276,7 +276,7 @@ CREATE TABLE IF NOT EXISTS property_device_hist (
 
 CREATE TABLE IF NOT EXISTS property_class_hist (
   id bigint unsigned NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   class varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
   count int(11) NOT NULL default '0',
@@ -287,7 +287,7 @@ CREATE TABLE IF NOT EXISTS property_class_hist (
 
 CREATE TABLE IF NOT EXISTS property_attribute_class_hist (
   id bigint unsigned NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   class varchar(255) NOT NULL default '',
   attribute varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
@@ -300,7 +300,7 @@ CREATE TABLE IF NOT EXISTS property_attribute_class_hist (
 CREATE TABLE IF NOT EXISTS property_attribute_device_hist (
   id bigint unsigned NOT NULL default '0',
   count int(11) NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   device varchar(255) NOT NULL default '',
   attribute varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
@@ -311,7 +311,7 @@ CREATE TABLE IF NOT EXISTS property_attribute_device_hist (
 
 CREATE TABLE IF NOT EXISTS property_pipe_class_hist (
   id bigint unsigned NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   class varchar(255) NOT NULL default '',
   pipe varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
@@ -323,7 +323,7 @@ CREATE TABLE IF NOT EXISTS property_pipe_class_hist (
 
 CREATE TABLE IF NOT EXISTS property_pipe_device_hist (
   id bigint unsigned NOT NULL default '0',
-  date timestamp NOT NULL,
+  date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   device varchar(255) NOT NULL default '',
   pipe varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
diff --git a/cppserver/database/test/test.cpp b/cppserver/database/test/test.cpp
index ef99003..504c3f2 100644
--- a/cppserver/database/test/test.cpp
+++ b/cppserver/database/test/test.cpp
@@ -234,4 +234,31 @@ BOOST_FIXTURE_TEST_SUITE(AllTests, Fixture)
     }
   }
 
+  BOOST_AUTO_TEST_CASE(DbPutPropertyWorks)
+  {
+    const std::string objName{"globalObj"};
+    const std::string propName{"propName"};
+    const std::string propValue{"propValue"};
+
+    // write free property
+    {
+      auto in = MakeDeviceDataStringArray({objName, "1", propName, "1", propValue});
+
+      Tango::DeviceData reply;
+      BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbPutProperty", in));
+    }
+
+    // read it back
+    {
+      auto in = MakeDeviceDataStringArray({objName, propName});
+
+      Tango::DeviceData reply;
+      BOOST_CHECK_NO_THROW(reply = dp->command_inout("DbGetProperty", in));
+
+      auto vec = ExtractStringVector(reply);
+      std::vector<std::string> ref = {objName, "1", propName, "1", propValue};
+      BOOST_CHECK_EQUAL_COLLECTIONS(std::begin(vec), std::end(vec), std::begin(ref), std::end(ref));
+    }
+  }
+
 BOOST_AUTO_TEST_SUITE_END() // AllTests
diff --git a/cppserver/database/update_db_from_5.23_to_5.24.sql.in b/cppserver/database/update_db_from_5.23_to_5.24.sql.in
new file mode 100644
index 0000000..527d27e
--- /dev/null
+++ b/cppserver/database/update_db_from_5.23_to_5.24.sql.in
@@ -0,0 +1,11 @@
+# vim: filetype=mysql:
+
+USE @TANGO_DB_NAME@;
+
+ALTER TABLE property_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+ALTER TABLE property_device_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+ALTER TABLE property_class_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+ALTER TABLE property_attribute_class_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+ALTER TABLE property_attribute_device_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+ALTER TABLE property_pipe_class_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+ALTER TABLE property_pipe_device_hist MODIFY date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
-- 
2.39.5

