Mercurial > hg > orthanc-databases
comparison Odbc/Plugins/StoragePlugin.cpp @ 329:b5fb8b77ce4d
initial commit of ODBC framework
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 10 Aug 2021 20:08:53 +0200 |
parents | |
children | 674bbb9d1c83 |
comparison
equal
deleted
inserted
replaced
328:6a49c495c940 | 329:b5fb8b77ce4d |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2021 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "../../Framework/Odbc/OdbcDatabase.h" | |
23 #include "../../Framework/Plugins/PluginInitialization.h" | |
24 #include "../../Framework/Plugins/StorageBackend.h" | |
25 #include "../../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" | |
26 | |
27 #include <EmbeddedResources.h> // Autogenerated file | |
28 | |
29 #include <Logging.h> | |
30 | |
31 | |
32 namespace OrthancDatabases | |
33 { | |
34 class OdbcStorageArea : public StorageBackend | |
35 { | |
36 protected: | |
37 virtual bool HasReadRange() const ORTHANC_OVERRIDE | |
38 { | |
39 // Read range is only available in native PostgreSQL/MySQL plugins | |
40 return false; | |
41 } | |
42 | |
43 public: | |
44 OdbcStorageArea(unsigned int maxConnectionRetries, | |
45 unsigned int connectionRetryInterval, | |
46 const std::string& connectionString) : | |
47 StorageBackend(OdbcDatabase::CreateDatabaseFactory( | |
48 maxConnectionRetries, connectionRetryInterval, connectionString, false), | |
49 maxConnectionRetries) | |
50 { | |
51 { | |
52 AccessorBase accessor(*this); | |
53 OdbcDatabase& db = dynamic_cast<OdbcDatabase&>(accessor.GetManager().GetDatabase()); | |
54 | |
55 if (!db.DoesTableExist("storagearea")) | |
56 { | |
57 std::string sql; | |
58 Orthanc::EmbeddedResources::GetFileResource(sql, Orthanc::EmbeddedResources::ODBC_PREPARE_STORAGE); | |
59 | |
60 switch (db.GetDialect()) | |
61 { | |
62 case Dialect_SQLite: | |
63 boost::replace_all(sql, "${BINARY}", "BLOB"); | |
64 break; | |
65 | |
66 case Dialect_PostgreSQL: | |
67 boost::replace_all(sql, "${BINARY}", "BYTEA"); | |
68 break; | |
69 | |
70 case Dialect_MySQL: | |
71 boost::replace_all(sql, "${BINARY}", "LONGBLOB"); | |
72 break; | |
73 | |
74 case Dialect_MSSQL: | |
75 boost::replace_all(sql, "${BINARY}", "VARBINARY(MAX)"); | |
76 break; | |
77 | |
78 default: | |
79 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
80 } | |
81 | |
82 { | |
83 DatabaseManager::Transaction t(accessor.GetManager(), TransactionType_ReadWrite); | |
84 db.ExecuteMultiLines(sql); | |
85 t.Commit(); | |
86 } | |
87 } | |
88 } | |
89 } | |
90 }; | |
91 } | |
92 | |
93 | |
94 | |
95 #if defined(_WIN32) | |
96 # include <windows.h> | |
97 #else | |
98 # include <ltdl.h> | |
99 # include <libltdl/lt_dlloader.h> | |
100 #endif | |
101 | |
102 | |
103 static const char* const KEY_ODBC = "Odbc"; | |
104 | |
105 | |
106 extern "C" | |
107 { | |
108 #if !defined(_WIN32) | |
109 extern lt_dlvtable *dlopen_LTX_get_vtable(lt_user_data loader_data); | |
110 #endif | |
111 | |
112 | |
113 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) | |
114 { | |
115 if (!OrthancDatabases::InitializePlugin(context, "ODBC", false)) | |
116 { | |
117 return -1; | |
118 } | |
119 | |
120 #if !defined(_WIN32) | |
121 lt_dlinit(); | |
122 | |
123 /** | |
124 * The following call is necessary for "libltdl" to access the | |
125 * "dlopen()" primitives if statically linking. Otherwise, only the | |
126 * "preopen" primitives are available. | |
127 **/ | |
128 lt_dlloader_add(dlopen_LTX_get_vtable(NULL)); | |
129 #endif | |
130 | |
131 OrthancPlugins::OrthancConfiguration configuration; | |
132 | |
133 if (!configuration.IsSection(KEY_ODBC)) | |
134 { | |
135 LOG(WARNING) << "No available configuration for the ODBC storage area plugin"; | |
136 return 0; | |
137 } | |
138 | |
139 OrthancPlugins::OrthancConfiguration odbc; | |
140 configuration.GetSection(odbc, KEY_ODBC); | |
141 | |
142 bool enable; | |
143 if (!odbc.LookupBooleanValue(enable, "EnableStorage") || | |
144 !enable) | |
145 { | |
146 LOG(WARNING) << "The ODBC storage area is currently disabled, set \"EnableStorage\" " | |
147 << "to \"true\" in the \"" << KEY_ODBC << "\" section of the configuration file of Orthanc"; | |
148 return 0; | |
149 } | |
150 | |
151 try | |
152 { | |
153 const std::string connectionString = odbc.GetStringValue("StorageConnectionString", ""); | |
154 const unsigned int maxConnectionRetries = odbc.GetUnsignedIntegerValue("MaxConnectionRetries", 10); | |
155 const unsigned int connectionRetryInterval = odbc.GetUnsignedIntegerValue("ConnectionRetryInterval", 5); | |
156 | |
157 if (connectionString.empty()) | |
158 { | |
159 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, | |
160 "No connection string provided for the ODBC storage area"); | |
161 } | |
162 | |
163 OrthancDatabases::StorageBackend::Register( | |
164 context, new OrthancDatabases::OdbcStorageArea( | |
165 maxConnectionRetries, connectionRetryInterval, connectionString)); | |
166 } | |
167 catch (Orthanc::OrthancException& e) | |
168 { | |
169 LOG(ERROR) << e.What(); | |
170 return -1; | |
171 } | |
172 catch (...) | |
173 { | |
174 LOG(ERROR) << "Native exception while initializing the plugin"; | |
175 return -1; | |
176 } | |
177 | |
178 return 0; | |
179 } | |
180 | |
181 | |
182 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
183 { | |
184 LOG(WARNING) << "ODBC storage area is finalizing"; | |
185 OrthancDatabases::StorageBackend::Finalize(); | |
186 } | |
187 | |
188 | |
189 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
190 { | |
191 return "odbc-storage"; | |
192 } | |
193 | |
194 | |
195 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
196 { | |
197 return ORTHANC_PLUGIN_VERSION; | |
198 } | |
199 } |