changeset 699:2929e17f8447

add attachments to resources
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 05 Feb 2014 17:49:30 +0100
parents aae83e1e31f7
children 0fe6632864b9
files OrthancServer/DatabaseWrapper.cpp OrthancServer/DatabaseWrapper.h OrthancServer/OrthancRestApi.cpp OrthancServer/ServerContext.cpp OrthancServer/ServerContext.h OrthancServer/ServerIndex.cpp OrthancServer/ServerIndex.h
diffstat 7 files changed, 98 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/DatabaseWrapper.cpp	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/DatabaseWrapper.cpp	Wed Feb 05 17:49:30 2014 +0100
@@ -459,6 +459,18 @@
     s.Run();
   }
 
+
+  void DatabaseWrapper::DeleteAttachment(int64_t id,
+                                         FileContentType attachment)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM Resources WHERE internalId=?");
+    s.BindInt64(0, id);
+    s.BindInt(1, attachment);
+    s.Run();
+  }
+
+
+
   void DatabaseWrapper::ListAvailableAttachments(std::list<FileContentType>& result,
                                                  int64_t id)
   {
--- a/OrthancServer/DatabaseWrapper.h	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/DatabaseWrapper.h	Wed Feb 05 17:49:30 2014 +0100
@@ -129,6 +129,9 @@
     void AddAttachment(int64_t id,
                        const FileInfo& attachment);
 
+    void DeleteAttachment(int64_t id,
+                          FileContentType attachment);
+
     void ListAvailableAttachments(std::list<FileContentType>& result,
                                   int64_t id);
 
--- a/OrthancServer/OrthancRestApi.cpp	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/OrthancRestApi.cpp	Wed Feb 05 17:49:30 2014 +0100
@@ -2018,6 +2018,23 @@
   }
 
 
+  static void UploadAttachment(RestApi::PostCall& call)
+  {
+    RETRIEVE_CONTEXT(call);
+    CheckValidResourceType(call);
+ 
+    std::string publicId = call.GetUriComponent("id", "");
+    std::string name = call.GetUriComponent("name", "");
+
+    const void* data = call.GetPostBody().size() ? &call.GetPostBody()[0] : NULL;
+
+    if (context.AddAttachment(publicId, StringToContentType(name), data, call.GetPostBody().size()))
+    {
+      call.GetOutput().AnswerBuffer("{}", "application/json");
+    }
+  }
+
+
 
   // Registration of the various REST handlers --------------------------------
 
@@ -2073,6 +2090,7 @@
     Register("/{resourceType}/{id}/attachments/{name}/md5", GetAttachmentMD5);
     Register("/{resourceType}/{id}/attachments/{name}/size", GetAttachmentSize);
     Register("/{resourceType}/{id}/attachments/{name}/verify-md5", VerifyAttachment);
+    Register("/{resourceType}/{id}/attachments/{name}", UploadAttachment);
 
     Register("/patients/{id}/protected", IsProtectedPatient);
     Register("/patients/{id}/protected", SetPatientProtection);
--- a/OrthancServer/ServerContext.cpp	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/ServerContext.cpp	Wed Feb 05 17:49:30 2014 +0100
@@ -284,4 +284,34 @@
     accessor_.SetStoreMD5(storeMD5);
   }
 
+
+  bool ServerContext::AddAttachment(const std::string& resourceId,
+                                    FileContentType attachmentType,
+                                    const void* data,
+                                    size_t size)
+  {
+    LOG(INFO) << "Adding attachment " << EnumerationToString(attachmentType) << " to resource " << resourceId;
+    
+    if (compressionEnabled_)
+    {
+      accessor_.SetCompressionForNextOperations(CompressionType_Zlib);
+    }
+    else
+    {
+      accessor_.SetCompressionForNextOperations(CompressionType_None);
+    }      
+
+    FileInfo info = accessor_.Write(data, size, attachmentType);
+    StoreStatus status = index_.AddAttachment(info, resourceId);
+
+    if (status != StoreStatus_Success)
+    {
+      storage_.Remove(info.GetUuid());
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
 }
--- a/OrthancServer/ServerContext.h	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/ServerContext.h	Wed Feb 05 17:49:30 2014 +0100
@@ -91,6 +91,11 @@
 
     void RemoveFile(const std::string& fileUuid);
 
+    bool AddAttachment(const std::string& resourceId,
+                       FileContentType attachmentType,
+                       const void* data,
+                       size_t size);
+
     StoreStatus Store(const char* dicomInstance,
                       size_t dicomSize,
                       const DicomMap& dicomSummary,
--- a/OrthancServer/ServerIndex.cpp	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/ServerIndex.cpp	Wed Feb 05 17:49:30 2014 +0100
@@ -1593,4 +1593,30 @@
       result.push_back(db_->GetPublicId(*it));
     }
   }
+
+
+  StoreStatus ServerIndex::AddAttachment(const FileInfo& attachment,
+                                         const std::string& publicId)
+  {
+    boost::mutex::scoped_lock lock(mutex_);
+
+    Transaction t(*this);
+
+    ResourceType resourceType;
+    int64_t resourceId;
+    if (!db_->LookupResource(publicId, resourceId, resourceType))
+    {
+      return StoreStatus_Failure;  // Inexistent resource
+    }
+
+    db_->DeleteAttachment(resourceId, attachment.GetContentType());
+
+    // TODO Integrate the recycling mechanism!!
+    db_->AddAttachment(resourceId, attachment);
+
+    t.Commit(attachment.GetCompressedSize());
+
+    return StoreStatus_Success;
+  }
+
 }
--- a/OrthancServer/ServerIndex.h	Wed Feb 05 17:20:43 2014 +0100
+++ b/OrthancServer/ServerIndex.h	Wed Feb 05 17:49:30 2014 +0100
@@ -217,5 +217,9 @@
 
     void LookupTagValue(std::list<std::string>& result,
                         const std::string& value);
+
+    StoreStatus AddAttachment(const FileInfo& attachment,
+                              const std::string& publicId);
+
   };
 }