Mercurial > hg > orthanc
comparison OrthancServer/Sources/ServerIndex.cpp @ 4563:bb1c365f9e44 db-changes
end of refactoring read-only transactions
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 05 Mar 2021 16:11:11 +0100 |
parents | e19f11e08226 |
children | 5a0adc1c19a9 |
comparison
equal
deleted
inserted
replaced
4562:e19f11e08226 | 4563:bb1c365f9e44 |
---|---|
1658 } | 1658 } |
1659 | 1659 |
1660 | 1660 |
1661 | 1661 |
1662 | 1662 |
1663 bool ServerIndex::GetAllMainDicomTags(DicomMap& result, | |
1664 const std::string& instancePublicId) | |
1665 { | |
1666 result.Clear(); | |
1667 | |
1668 boost::mutex::scoped_lock lock(mutex_); | |
1669 | |
1670 // Lookup for the requested resource | |
1671 int64_t instance; | |
1672 ResourceType type; | |
1673 if (!db_.LookupResource(instance, type, instancePublicId) || | |
1674 type != ResourceType_Instance) | |
1675 { | |
1676 return false; | |
1677 } | |
1678 else | |
1679 { | |
1680 DicomMap tmp; | |
1681 | |
1682 db_.GetMainDicomTags(tmp, instance); | |
1683 result.Merge(tmp); | |
1684 | |
1685 int64_t series; | |
1686 if (!db_.LookupParent(series, instance)) | |
1687 { | |
1688 throw OrthancException(ErrorCode_InternalError); | |
1689 } | |
1690 | |
1691 tmp.Clear(); | |
1692 db_.GetMainDicomTags(tmp, series); | |
1693 result.Merge(tmp); | |
1694 | |
1695 int64_t study; | |
1696 if (!db_.LookupParent(study, series)) | |
1697 { | |
1698 throw OrthancException(ErrorCode_InternalError); | |
1699 } | |
1700 | |
1701 tmp.Clear(); | |
1702 db_.GetMainDicomTags(tmp, study); | |
1703 result.Merge(tmp); | |
1704 | |
1705 #ifndef NDEBUG | |
1706 { | |
1707 // Sanity test to check that all the main DICOM tags from the | |
1708 // patient level are copied at the study level | |
1709 | |
1710 int64_t patient; | |
1711 if (!db_.LookupParent(patient, study)) | |
1712 { | |
1713 throw OrthancException(ErrorCode_InternalError); | |
1714 } | |
1715 | |
1716 tmp.Clear(); | |
1717 db_.GetMainDicomTags(tmp, study); | |
1718 | |
1719 std::set<DicomTag> patientTags; | |
1720 tmp.GetTags(patientTags); | |
1721 | |
1722 for (std::set<DicomTag>::const_iterator | |
1723 it = patientTags.begin(); it != patientTags.end(); ++it) | |
1724 { | |
1725 assert(result.HasTag(*it)); | |
1726 } | |
1727 } | |
1728 #endif | |
1729 | |
1730 return true; | |
1731 } | |
1732 } | |
1733 | |
1734 | |
1735 bool ServerIndex::LookupResourceType(ResourceType& type, | |
1736 const std::string& publicId) | |
1737 { | |
1738 boost::mutex::scoped_lock lock(mutex_); | |
1739 | |
1740 int64_t id; | |
1741 return db_.LookupResource(id, type, publicId); | |
1742 } | |
1743 | |
1744 | |
1745 unsigned int ServerIndex::GetDatabaseVersion() | |
1746 { | |
1747 boost::mutex::scoped_lock lock(mutex_); | |
1748 return db_.GetDatabaseVersion(); | |
1749 } | |
1750 | |
1751 | |
1752 bool ServerIndex::LookupParent(std::string& target, | |
1753 const std::string& publicId, | |
1754 ResourceType parentType) | |
1755 { | |
1756 boost::mutex::scoped_lock lock(mutex_); | |
1757 | |
1758 ResourceType type; | |
1759 int64_t id; | |
1760 if (!db_.LookupResource(id, type, publicId)) | |
1761 { | |
1762 throw OrthancException(ErrorCode_UnknownResource); | |
1763 } | |
1764 | |
1765 while (type != parentType) | |
1766 { | |
1767 int64_t parentId; | |
1768 | |
1769 if (type == ResourceType_Patient || // Cannot further go up in hierarchy | |
1770 !db_.LookupParent(parentId, id)) | |
1771 { | |
1772 return false; | |
1773 } | |
1774 | |
1775 id = parentId; | |
1776 type = GetParentResourceType(type); | |
1777 } | |
1778 | |
1779 target = db_.GetPublicId(id); | |
1780 return true; | |
1781 } | |
1782 | |
1783 | |
1784 void ServerIndex::ReconstructInstance(const ParsedDicomFile& dicom) | 1663 void ServerIndex::ReconstructInstance(const ParsedDicomFile& dicom) |
1785 { | 1664 { |
1786 DicomMap summary; | 1665 DicomMap summary; |
1787 OrthancConfiguration::DefaultExtractDicomSummary(summary, dicom); | 1666 OrthancConfiguration::DefaultExtractDicomSummary(summary, dicom); |
1788 | 1667 |
1874 level = ResourceType_Study; | 1753 level = ResourceType_Study; |
1875 } | 1754 } |
1876 | 1755 |
1877 target.push_back(source.GetConstraint(i).ConvertToDatabaseConstraint(level, type)); | 1756 target.push_back(source.GetConstraint(i).ConvertToDatabaseConstraint(level, type)); |
1878 } | 1757 } |
1879 } | |
1880 } | |
1881 | |
1882 | |
1883 void ServerIndex::ApplyLookupResources(std::vector<std::string>& resourcesId, | |
1884 std::vector<std::string>* instancesId, | |
1885 const DatabaseLookup& lookup, | |
1886 ResourceType queryLevel, | |
1887 size_t limit) | |
1888 { | |
1889 std::vector<DatabaseConstraint> normalized; | |
1890 NormalizeLookup(normalized, lookup, queryLevel); | |
1891 | |
1892 std::list<std::string> resourcesList, instancesList; | |
1893 | |
1894 { | |
1895 boost::mutex::scoped_lock lock(mutex_); | |
1896 | |
1897 if (instancesId == NULL) | |
1898 { | |
1899 db_.ApplyLookupResources(resourcesList, NULL, normalized, queryLevel, limit); | |
1900 } | |
1901 else | |
1902 { | |
1903 db_.ApplyLookupResources(resourcesList, &instancesList, normalized, queryLevel, limit); | |
1904 } | |
1905 } | |
1906 | |
1907 CopyListToVector(resourcesId, resourcesList); | |
1908 | |
1909 if (instancesId != NULL) | |
1910 { | |
1911 CopyListToVector(*instancesId, instancesList); | |
1912 } | 1758 } |
1913 } | 1759 } |
1914 | 1760 |
1915 | 1761 |
1916 | 1762 |
3063 { | 2909 { |
3064 } | 2910 } |
3065 | 2911 |
3066 virtual void Apply(ReadOnlyTransaction& transaction) ORTHANC_OVERRIDE | 2912 virtual void Apply(ReadOnlyTransaction& transaction) ORTHANC_OVERRIDE |
3067 { | 2913 { |
2914 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" | |
3068 std::list<std::string> tmp; | 2915 std::list<std::string> tmp; |
3069 transaction.ApplyLookupResources(tmp, NULL, query_, level_, 0); | 2916 transaction.ApplyLookupResources(tmp, NULL, query_, level_, 0); |
3070 CopyListToVector(result_, tmp); | 2917 CopyListToVector(result_, tmp); |
3071 } | 2918 } |
3072 }; | 2919 }; |
3083 { | 2930 { |
3084 public: | 2931 public: |
3085 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | 2932 virtual void ApplyTuple(ReadOnlyTransaction& transaction, |
3086 const Tuple& tuple) ORTHANC_OVERRIDE | 2933 const Tuple& tuple) ORTHANC_OVERRIDE |
3087 { | 2934 { |
2935 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" | |
3088 *tuple.get<0>() = transaction.LookupGlobalProperty(*tuple.get<1>(), tuple.get<2>()); | 2936 *tuple.get<0>() = transaction.LookupGlobalProperty(*tuple.get<1>(), tuple.get<2>()); |
3089 } | 2937 } |
3090 }; | 2938 }; |
3091 | 2939 |
3092 bool found; | 2940 bool found; |
3097 | 2945 |
3098 | 2946 |
3099 std::string ServerIndex::GetGlobalProperty(GlobalProperty property, | 2947 std::string ServerIndex::GetGlobalProperty(GlobalProperty property, |
3100 const std::string& defaultValue) | 2948 const std::string& defaultValue) |
3101 { | 2949 { |
3102 class Operations : public ReadOnlyOperationsT3<std::string*, GlobalProperty, std::string> | |
3103 { | |
3104 public: | |
3105 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | |
3106 const Tuple& tuple) ORTHANC_OVERRIDE | |
3107 { | |
3108 if (!transaction.LookupGlobalProperty(*tuple.get<0>(), tuple.get<1>())) | |
3109 { | |
3110 *tuple.get<0>() = tuple.get<2>(); // Default value | |
3111 } | |
3112 } | |
3113 }; | |
3114 | |
3115 std::string s; | 2950 std::string s; |
3116 Operations operations; | 2951 if (LookupGlobalProperty(s, property)) |
3117 operations.Apply(*this, &s, property, defaultValue); | 2952 { |
3118 return s; | 2953 return s; |
2954 } | |
2955 else | |
2956 { | |
2957 return defaultValue; | |
2958 } | |
3119 } | 2959 } |
3120 | 2960 |
3121 | 2961 |
3122 bool ServerIndex::GetMainDicomTags(DicomMap& result, | 2962 bool ServerIndex::GetMainDicomTags(DicomMap& result, |
3123 const std::string& publicId, | 2963 const std::string& publicId, |
3183 bool found; | 3023 bool found; |
3184 Operations operations; | 3024 Operations operations; |
3185 operations.Apply(*this, &found, &result, publicId, expectedType, levelOfInterest); | 3025 operations.Apply(*this, &found, &result, publicId, expectedType, levelOfInterest); |
3186 return found; | 3026 return found; |
3187 } | 3027 } |
3028 | |
3029 | |
3030 bool ServerIndex::GetAllMainDicomTags(DicomMap& result, | |
3031 const std::string& instancePublicId) | |
3032 { | |
3033 class Operations : public ReadOnlyOperationsT3<bool*, DicomMap*, std::string> | |
3034 { | |
3035 public: | |
3036 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | |
3037 const Tuple& tuple) ORTHANC_OVERRIDE | |
3038 { | |
3039 // Lookup for the requested resource | |
3040 int64_t instance; | |
3041 ResourceType type; | |
3042 if (!transaction.LookupResource(instance, type, tuple.get<2>()) || | |
3043 type != ResourceType_Instance) | |
3044 { | |
3045 *tuple.get<0>() = false; | |
3046 } | |
3047 else | |
3048 { | |
3049 DicomMap tmp; | |
3050 | |
3051 transaction.GetMainDicomTags(tmp, instance); | |
3052 tuple.get<1>()->Merge(tmp); | |
3053 | |
3054 int64_t series; | |
3055 if (!transaction.LookupParent(series, instance)) | |
3056 { | |
3057 throw OrthancException(ErrorCode_InternalError); | |
3058 } | |
3059 | |
3060 tmp.Clear(); | |
3061 transaction.GetMainDicomTags(tmp, series); | |
3062 tuple.get<1>()->Merge(tmp); | |
3063 | |
3064 int64_t study; | |
3065 if (!transaction.LookupParent(study, series)) | |
3066 { | |
3067 throw OrthancException(ErrorCode_InternalError); | |
3068 } | |
3069 | |
3070 tmp.Clear(); | |
3071 transaction.GetMainDicomTags(tmp, study); | |
3072 tuple.get<1>()->Merge(tmp); | |
3073 | |
3074 #ifndef NDEBUG | |
3075 { | |
3076 // Sanity test to check that all the main DICOM tags from the | |
3077 // patient level are copied at the study level | |
3078 | |
3079 int64_t patient; | |
3080 if (!transaction.LookupParent(patient, study)) | |
3081 { | |
3082 throw OrthancException(ErrorCode_InternalError); | |
3083 } | |
3084 | |
3085 tmp.Clear(); | |
3086 transaction.GetMainDicomTags(tmp, study); | |
3087 | |
3088 std::set<DicomTag> patientTags; | |
3089 tmp.GetTags(patientTags); | |
3090 | |
3091 for (std::set<DicomTag>::const_iterator | |
3092 it = patientTags.begin(); it != patientTags.end(); ++it) | |
3093 { | |
3094 assert(tuple.get<1>()->HasTag(*it)); | |
3095 } | |
3096 } | |
3097 #endif | |
3098 | |
3099 *tuple.get<0>() = true; | |
3100 } | |
3101 } | |
3102 }; | |
3103 | |
3104 result.Clear(); | |
3105 | |
3106 bool found; | |
3107 Operations operations; | |
3108 operations.Apply(*this, &found, &result, instancePublicId); | |
3109 return found; | |
3110 } | |
3111 | |
3112 | |
3113 bool ServerIndex::LookupResourceType(ResourceType& type, | |
3114 const std::string& publicId) | |
3115 { | |
3116 class Operations : public ReadOnlyOperationsT3<bool*, ResourceType*, std::string> | |
3117 { | |
3118 public: | |
3119 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | |
3120 const Tuple& tuple) ORTHANC_OVERRIDE | |
3121 { | |
3122 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" | |
3123 int64_t id; | |
3124 *tuple.get<0>() = transaction.LookupResource(id, *tuple.get<1>(), tuple.get<2>()); | |
3125 } | |
3126 }; | |
3127 | |
3128 bool found; | |
3129 Operations operations; | |
3130 operations.Apply(*this, &found, &type, publicId); | |
3131 return found; | |
3132 } | |
3133 | |
3134 | |
3135 unsigned int ServerIndex::GetDatabaseVersion() | |
3136 { | |
3137 class Operations : public ReadOnlyOperationsT1<unsigned int *> | |
3138 { | |
3139 public: | |
3140 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | |
3141 const Tuple& tuple) ORTHANC_OVERRIDE | |
3142 { | |
3143 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" | |
3144 *tuple.get<0>() = transaction.GetDatabaseVersion(); | |
3145 } | |
3146 }; | |
3147 | |
3148 unsigned int version; | |
3149 Operations operations; | |
3150 operations.Apply(*this, &version); | |
3151 return version; | |
3152 } | |
3153 | |
3154 | |
3155 bool ServerIndex::LookupParent(std::string& target, | |
3156 const std::string& publicId, | |
3157 ResourceType parentType) | |
3158 { | |
3159 class Operations : public ReadOnlyOperationsT4<bool*, std::string*, std::string, ResourceType> | |
3160 { | |
3161 public: | |
3162 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | |
3163 const Tuple& tuple) ORTHANC_OVERRIDE | |
3164 { | |
3165 ResourceType type; | |
3166 int64_t id; | |
3167 if (!transaction.LookupResource(id, type, tuple.get<2>())) | |
3168 { | |
3169 throw OrthancException(ErrorCode_UnknownResource); | |
3170 } | |
3171 | |
3172 while (type != tuple.get<3>()) | |
3173 { | |
3174 int64_t parentId; | |
3175 | |
3176 if (type == ResourceType_Patient || // Cannot further go up in hierarchy | |
3177 !transaction.LookupParent(parentId, id)) | |
3178 { | |
3179 *tuple.get<0>() = false; | |
3180 return; | |
3181 } | |
3182 | |
3183 id = parentId; | |
3184 type = GetParentResourceType(type); | |
3185 } | |
3186 | |
3187 *tuple.get<0>() = true; | |
3188 *tuple.get<1>() = transaction.GetPublicId(id); | |
3189 } | |
3190 }; | |
3191 | |
3192 bool found; | |
3193 Operations operations; | |
3194 operations.Apply(*this, &found, &target, publicId, parentType); | |
3195 return found; | |
3196 } | |
3197 | |
3198 | |
3199 void ServerIndex::ApplyLookupResources(std::vector<std::string>& resourcesId, | |
3200 std::vector<std::string>* instancesId, | |
3201 const DatabaseLookup& lookup, | |
3202 ResourceType queryLevel, | |
3203 size_t limit) | |
3204 { | |
3205 class Operations : public ReadOnlyOperationsT4<bool, std::vector<DatabaseConstraint>, ResourceType, size_t> | |
3206 { | |
3207 private: | |
3208 std::list<std::string> resourcesList_; | |
3209 std::list<std::string> instancesList_; | |
3210 | |
3211 public: | |
3212 const std::list<std::string>& GetResourcesList() const | |
3213 { | |
3214 return resourcesList_; | |
3215 } | |
3216 | |
3217 const std::list<std::string>& GetInstancesList() const | |
3218 { | |
3219 return instancesList_; | |
3220 } | |
3221 | |
3222 virtual void ApplyTuple(ReadOnlyTransaction& transaction, | |
3223 const Tuple& tuple) ORTHANC_OVERRIDE | |
3224 { | |
3225 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" | |
3226 if (tuple.get<0>()) | |
3227 { | |
3228 transaction.ApplyLookupResources(resourcesList_, &instancesList_, tuple.get<1>(), tuple.get<2>(), tuple.get<3>()); | |
3229 } | |
3230 else | |
3231 { | |
3232 transaction.ApplyLookupResources(resourcesList_, NULL, tuple.get<1>(), tuple.get<2>(), tuple.get<3>()); | |
3233 } | |
3234 } | |
3235 }; | |
3236 | |
3237 | |
3238 std::vector<DatabaseConstraint> normalized; | |
3239 NormalizeLookup(normalized, lookup, queryLevel); | |
3240 | |
3241 Operations operations; | |
3242 operations.Apply(*this, (instancesId != NULL), normalized, queryLevel, limit); | |
3243 | |
3244 CopyListToVector(resourcesId, operations.GetResourcesList()); | |
3245 | |
3246 if (instancesId != NULL) | |
3247 { | |
3248 CopyListToVector(*instancesId, operations.GetInstancesList()); | |
3249 } | |
3250 } | |
3188 } | 3251 } |