changeset 663:41994c49b1f0 attach-custom-data

overwrite default Utf8String arg types + nullable Utf8String values
author Alain Mazy <am@orthanc.team>
date Wed, 21 May 2025 23:42:49 +0200 (4 weeks ago)
parents 133e785a87f5
children 48460f653628
files Framework/Common/DatabaseManager.cpp Framework/Common/DatabaseManager.h Framework/Common/Dictionary.cpp Framework/Common/Dictionary.h Framework/Common/IValue.h Framework/Common/Utf8StringValue.cpp Framework/Common/Utf8StringValue.h
diffstat 7 files changed, 55 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Common/DatabaseManager.cpp	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/DatabaseManager.cpp	Wed May 21 23:42:49 2025 +0200
@@ -99,7 +99,7 @@
                                                          const Query& query)
   {
     LOG(TRACE) << "Caching statement from " << statementId.GetFile() << ":" << statementId.GetLine() << "" << statementId.GetDynamicStatement();
-      
+    
     std::unique_ptr<IPrecompiledStatement> statement(GetDatabase().Compile(query));
       
     IPrecompiledStatement* tmp = statement.get();
@@ -394,6 +394,17 @@
   }
 
 
+  void DatabaseManager::StatementBase::SetParametersTypes(const Dictionary& parameters)
+  {
+    Dictionary::Types parametersTypes;
+    parameters.GetParametersType(parametersTypes);
+
+    for (Dictionary::Types::const_iterator it = parametersTypes.begin(); it != parametersTypes.end(); ++it)
+    {
+      SetParameterType(it->first, it->second);
+    }
+  }
+
   void DatabaseManager::StatementBase::SetParameterType(const std::string& parameter,
                                                         ValueType type)
   {
@@ -601,6 +612,9 @@
 
   void DatabaseManager::CachedStatement::ExecuteInternal(const Dictionary& parameters, bool withResults)
   {
+    // the query parameters_ type can not be trusted (they are all Utf8String by default), we need a parameters dico with the actual types
+    SetParametersTypes(parameters);
+
     try
     {
       std::unique_ptr<Query> query(ReleaseQuery());
@@ -609,7 +623,7 @@
       {
         // Register the newly-created statement
         assert(statement_ == NULL);
-        statement_ = &GetManager().CacheStatement(statementId_, *query);
+        statement_ = &GetManager().CacheStatement(statementId_, *query);  
       }
         
       assert(statement_ != NULL);
@@ -691,6 +705,9 @@
 
   void DatabaseManager::StandaloneStatement::ExecuteInternal(const Dictionary& parameters, bool withResults)
   {
+    // the query parameters_ type can not be trusted (they are all Utf8String by default), we need a parameters dico with the actual types
+    SetParametersTypes(parameters);
+
     try
     {
       std::unique_ptr<Query> query(ReleaseQuery());
--- a/Framework/Common/DatabaseManager.h	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/DatabaseManager.h	Wed May 21 23:42:49 2025 +0200
@@ -155,6 +155,8 @@
         return query_.release();
       }
 
+      void SetParametersTypes(const Dictionary& parameters);
+      
     public:
       explicit StatementBase(DatabaseManager& manager);
 
--- a/Framework/Common/Dictionary.cpp	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/Dictionary.cpp	Wed May 21 23:42:49 2025 +0200
@@ -134,9 +134,9 @@
     SetValue(key, new Integer32Value(value));
   }
 
-  void Dictionary::SetNullValue(const std::string& key)
+  void Dictionary::SetUtf8NullValue(const std::string& key)
   {
-    SetValue(key, new NullValue);
+    SetValue(key, new Utf8StringValue());
   }
 
   
--- a/Framework/Common/Dictionary.h	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/Dictionary.h	Wed May 21 23:42:49 2025 +0200
@@ -33,6 +33,8 @@
 {
   class Dictionary : public boost::noncopyable
   {
+  public:
+    typedef std::map<std::string, ValueType> Types;
   private:
     typedef std::map<std::string, IValue*>   Values;
 
@@ -56,6 +58,8 @@
     void SetUtf8Value(const std::string& key,
                       const std::string& utf8);
 
+    void SetUtf8NullValue(const std::string& key);
+
     void SetBinaryValue(const std::string& key,
                         const std::string& binary);
 
@@ -72,10 +76,10 @@
     void SetInteger32Value(const std::string& key,
                            int32_t value);
 
-    void SetNullValue(const std::string& key);
-
     const IValue& GetValue(const std::string& key) const;
 
     void GetParametersType(Query::Parameters& target) const;
+
+    void GetParametersTypes(Types& target) const;
   };
 }
--- a/Framework/Common/IValue.h	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/IValue.h	Wed May 21 23:42:49 2025 +0200
@@ -40,5 +40,10 @@
     virtual ValueType GetType() const = 0;
 
     virtual IValue* Convert(ValueType target) const = 0;
+
+    virtual bool IsNull() const  // TODO: right now, only the Utf8StringValue implements nullable values
+    {
+      return false;
+    }
   };
 }
--- a/Framework/Common/Utf8StringValue.cpp	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/Utf8StringValue.cpp	Wed May 21 23:42:49 2025 +0200
@@ -57,7 +57,14 @@
         break;
 
       case ValueType_Utf8String:
-        return new Utf8StringValue(utf8_);
+        if (IsNull())
+        {
+          return new Utf8StringValue();
+        }
+        else
+        {
+          return new Utf8StringValue(utf8_);
+        }
 
       default:
         throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
--- a/Framework/Common/Utf8StringValue.h	Wed May 21 22:53:18 2025 +0200
+++ b/Framework/Common/Utf8StringValue.h	Wed May 21 23:42:49 2025 +0200
@@ -34,13 +34,25 @@
   {
   private:
     std::string  utf8_;
+    bool isNull_;
 
   public:
     explicit Utf8StringValue(const std::string& utf8) :
-      utf8_(utf8)
+      utf8_(utf8),
+      isNull_(false)
     {
     }
 
+    explicit Utf8StringValue() :
+      isNull_(true)
+    {
+    }
+
+    virtual bool IsNull() const ORTHANC_OVERRIDE
+    {
+      return isNull_;
+    }
+    
     const std::string& GetContent() const
     {
       return utf8_;