750
|
1 .. _odbc:
|
|
2
|
|
3
|
|
4 ODBC plugins
|
|
5 ============
|
|
6
|
|
7 .. contents::
|
|
8
|
|
9 The Orthanc project provides two **official** plugins to replace the
|
|
10 default storage area (on the filesystem) and the default SQLite index
|
|
11 by a `ODBC database
|
|
12 <https://en.wikipedia.org/wiki/Open_Database_Connectivity>`__. This
|
|
13 can notably be used to connect Orthanc to Microsoft SQL Server.
|
|
14
|
|
15 The source code of the ODBC plugins can be found in the
|
|
16 ``orthanc-databases`` `Mercurial repository
|
|
17 <https://hg.orthanc-server.com/orthanc-databases/>`__, next to the
|
|
18 source code of the :ref:`PostgreSQL <postgresql>` and
|
|
19 :ref:`MySQL/MariaDB <mysql>` plugins.
|
|
20
|
|
21
|
|
22 When to use ODBC?
|
|
23 -----------------
|
|
24
|
|
25 In general, you'll always get better performance by using native C/C++
|
|
26 plugins dedicated to one single database engine, instead of the ODBC
|
|
27 plugins that can connect to any database driver. This is the price of
|
|
28 genericity: Some specific optimisations can only be done if focusing
|
|
29 on one single database.
|
|
30
|
|
31 That being said, there are multiple use cases for the ODBC plugins:
|
|
32
|
|
33 * Connection to Microsoft SQL Server (MSSQL) is only possible with
|
|
34 ODBC. Note that the ODBC plugins were only validated against MSSQL
|
|
35 2017 and MSSQL 2019, under GNU/Linux.
|
|
36
|
|
37 * Contrarily to the built-in SQLite engine and to the MySQL/MariaDB
|
|
38 index plugin, the ODBC index plugin supports the :ref:`revision
|
|
39 mechanism <revisions>` to protect metadata and attachments from
|
|
40 concurrent modifications.
|
|
41
|
|
42 * Because of its genericity, the ODBC storage area plugin does not
|
|
43 implement the :ref:`read-range primitive <registry>`. As a
|
|
44 consequence, using it will write two attachments for each stored
|
|
45 DICOM instance (namely, ``Attachment 1`` that corresponds to the
|
|
46 DICOM instance itself, and ``Attachment 3`` that corresponds to the
|
|
47 tags before the pixel data).
|
|
48
|
|
49 * The Linux Standard Base (LSB) `pre-compiled binaries
|
|
50 <https://lsb.orthanc-server.com/plugin-odbc/>`__ of the ODBC plugins
|
|
51 are not compatible with the ``libsqliteodbc`` `Debian/Ubuntu package
|
|
52 <http://www.ch-werner.de/sqliteodbc/>`__ because the latter package
|
|
53 was compiled with the ``HAVE_SQLITE3LOADEXTENSION`` flag.
|
|
54
|
|
55 * Finally, make sure to read the :ref:`recommended setup for best
|
|
56 scalability <scalability>`.
|
|
57
|
|
58 Very importantly, pay attention to the fact that the ODBC plugins use
|
|
59 a different database schema than the built-in SQLite driver, and than
|
|
60 the PostgreSQL/MariaDB/MySQL plugins. As a consequence, it is **not
|
|
61 possible to switch back and forth** between ODBC and the native
|
|
62 drivers without running a :ref:`full replication procedure
|
|
63 <replication>`. As a consequence, pay attention to choose the right
|
|
64 plugin from the beginning, as you will need to stick to it.
|
|
65
|
|
66 Summarizing, here are two tables containing our recommendations about
|
|
67 when to use the ODBC plugins:
|
|
68
|
|
69 +------------------------------+--------------------------------------------------------+
|
|
70 | Database management system | Recommended index plugin |
|
|
71 +==============================+========================================================+
|
|
72 | Microsoft SQL server (MSSQL) | ODBC plugin |
|
|
73 +------------------------------+--------------------------------------------------------+
|
|
74 | MySQL (with revisions) | ODBC plugin |
|
|
75 +------------------------------+--------------------------------------------------------+
|
|
76 | MySQL (without revisions) | :ref:`MySQL plugin <mysql>` |
|
|
77 +------------------------------+--------------------------------------------------------+
|
|
78 | PostgreSQL | :ref:`PostgreSQL plugin <postgresql>` |
|
|
79 +------------------------------+--------------------------------------------------------+
|
|
80 | SQLite (with revisions) | ODBC plugin |
|
|
81 +------------------------------+--------------------------------------------------------+
|
|
82 | SQLite (without revisions) | No plugin needed |
|
|
83 +------------------------------+--------------------------------------------------------+
|
|
84 | Other | Create a :ref:`dedicated plugin <creating-plugins>` |
|
|
85 | | or implement a new dialect in the ODBC plugins |
|
|
86 +------------------------------+--------------------------------------------------------+
|
|
87
|
|
88
|
|
89 +------------------------------+--------------------------------------------------------+
|
|
90 | Type of storage area | Recommended storage plugin |
|
|
91 +==============================+========================================================+
|
|
92 | Filesystem | No plugin needed |
|
|
93 +------------------------------+--------------------------------------------------------+
|
|
94 | Microsoft SQL server (MSSQL) | ODBC plugin |
|
|
95 +------------------------------+--------------------------------------------------------+
|
|
96 | MySQL | :ref:`MySQL plugin <mysql>` |
|
|
97 +------------------------------+--------------------------------------------------------+
|
|
98 | PostgreSQL | :ref:`PostgreSQL plugin <postgresql>` |
|
|
99 +------------------------------+--------------------------------------------------------+
|
|
100 | SQLite | ODBC plugin |
|
|
101 +------------------------------+--------------------------------------------------------+
|
|
102 | Google Cloud Storage, Azure | :ref:`Cloud object storage plugins <object-storage>` |
|
|
103 | blob storage, AWS S3 | |
|
|
104 +------------------------------+--------------------------------------------------------+
|
|
105 | Other | Create a :ref:`dedicated plugin <creating-plugins>`, |
|
|
106 | | implement a new dialect in the ODBC plugins, |
|
|
107 | | or prototype using :ref:`Python <python_storage_area>` |
|
|
108 +------------------------------+--------------------------------------------------------+
|
|
109
|
|
110
|
|
111 Compilation
|
|
112 -----------
|
|
113
|
|
114 Static linking
|
|
115 ^^^^^^^^^^^^^^
|
|
116
|
|
117 .. highlight:: text
|
|
118
|
|
119 The procedure to compile these plugins is similar to that for the
|
|
120 :ref:`core of Orthanc <compiling>`. The following commands should work
|
|
121 for most UNIX-like distribution (including GNU/Linux)::
|
|
122
|
|
123 $ mkdir BuildOdbc
|
|
124 $ cd BuildOdbc
|
|
125 $ cmake ../Odbc -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release
|
|
126 $ make
|
|
127
|
|
128 The compilation will produce 2 shared libraries, each containing one plugin for Orthanc:
|
|
129
|
|
130 * ``OrthancOdbcIndex`` replaces the default SQLite index of Orthanc by ODBC.
|
|
131 * ``OrthancOdbcStorage`` makes Orthanc store the DICOM files it receives into ODBC.
|
|
132
|
|
133
|
|
134 Microsoft Windows and Apple OS X
|
|
135 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
136
|
|
137 Pre-compiled binaries for Microsoft Windows 32bit `are also available
|
|
138 <https://www.orthanc-server.com/browse.php?path=/plugin-odbc>`__. A
|
|
139 package for `Apple's Mac OS X
|
|
140 <https://www.osimis.io/en/download.html>`__ is available courtesy of
|
|
141 `Osimis <https://www.osimis.io/>`__.
|
|
142
|
|
143
|
|
144 .. _odbc-ubuntu1604:
|
|
145
|
|
146 Dynamic linking on Ubuntu 16.04
|
|
147 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
148
|
|
149 .. highlight:: text
|
|
150
|
|
151 If static linking is not desired, here are build instructions for
|
|
152 Ubuntu 16.04 (provided build dependencies for the :ref:`core of
|
|
153 Orthanc <compiling>` have already been installed)::
|
|
154
|
|
155 $ sudo apt-get install libodbc1 unixodbc unixodbc-dev
|
|
156 $ mkdir BuildOdbc
|
|
157 $ cd BuildOdbc
|
|
158 $ cmake ../Odbc -DCMAKE_BUILD_TYPE=Release \
|
|
159 -DALLOW_DOWNLOADS=ON \
|
|
160 -DUSE_SYSTEM_GOOGLE_TEST=OFF \
|
|
161 -DUSE_SYSTEM_ORTHANC_SDK=OFF
|
|
162 $ make
|
|
163
|
|
164
|
|
165
|
|
166 Usage
|
|
167 -----
|
|
168
|
|
169 .. highlight:: json
|
|
170
|
|
171 You of course first have to :ref:`install Orthanc <binaries>`, with a
|
|
172 version above 0.9.5. You then have to **configure an ODBC data
|
|
173 source** dedicated to Orthanc. The procedure depends upon your
|
|
174 operating system:
|
|
175
|
|
176 * Many UNIX-like platforms (including Debian and Ubuntu) use `unixODBC
|
|
177 <https://en.wikipedia.org/wiki/UnixODBC>`__. You first have to
|
|
178 install at least one ODBC driver (e.g. on Debian, installing the
|
|
179 packages ``libsqliteodbc`` and ``odbc-postgresql`` will respectively
|
|
180 install the driver for SQLite and for PostgreSQL). Secondly, you
|
|
181 have to edit your ``~/.odbc.ini`` to define the data sources
|
|
182 (i.e. the actual databases).
|
|
183
|
|
184 * On Microsoft Windows, the configuration tool ``odbcad32.exe`` ("ODBC
|
|
185 Data Source Administrator") allows to define the data sources. You
|
|
186 also have to install at least one ODBC driver. For instance, the
|
|
187 `SQLite ODBC Driver <http://www.ch-werner.de/sqliteodbc/>`__ can be
|
|
188 used to access SQLite.
|
|
189
|
|
190 * If you are interested in interfacing Orthanc with Microsoft SQL
|
|
191 Server, the corresponding ODBC drivers can be `downloaded from
|
|
192 Microsoft
|
|
193 <https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server>`__.
|
|
194
|
|
195 Once Orthanc is installed and the data sources have been defined, you
|
|
196 must add a section in the :ref:`configuration file <configuration>`
|
|
197 that specifies the **data source(s) to be used**. You also have to
|
|
198 tell Orthanc in which path it can find the plugins: This is done by
|
|
199 properly modifying the ``Plugins`` option. You could for instance
|
|
200 adapt the following configuration file::
|
|
201
|
|
202 {
|
|
203 "Name" : "MyOrthanc",
|
|
204 "Odbc" : {
|
|
205 "EnableIndex" : true,
|
|
206 "EnableStorage" : true,
|
|
207 "IndexConnectionString" : "DSN=index",
|
|
208 "StorageConnectionString" : "DSN=storage",
|
|
209 "MaximumConnectionRetries" : 10, // Optional
|
|
210 "ConnectionRetryInterval" : 5, // Optional
|
|
211 "IndexConnectionsCount" : 1 // Optional
|
|
212 },
|
|
213 "Plugins" : [
|
|
214 "/home/user/orthanc-databases/BuildOdbc/libOrthancOdbcIndex.so",
|
|
215 "/home/user/orthanc-databases/BuildOdbc/libOrthancOdbcStorage.so"
|
|
216 ]
|
|
217 }
|
|
218
|
|
219 The values of ``IndexConnectionString`` and
|
|
220 ``StorageConnectionString`` are known as `ODBC connection strings
|
|
221 <https://www.connectionstrings.com/>`__, and define how to connect to
|
|
222 the ODBC data source. These connection strings are specific to the
|
|
223 different types of ODBC drivers. In the following sections, we'll
|
|
224 review connection strings for SQLite, PostgreSQL, MySQL and Microsoft
|
|
225 SQL Server.
|
|
226
|
|
227 **Important:** The ``EnableIndex`` and ``EnableStorage`` options must
|
|
228 be explicitly set to ``true``, otherwise Orthanc will continue to use
|
|
229 its default SQLite back-end and the filesystem storage area.
|
|
230
|
|
231 **Remark 1:** When using the ODBC storage area plugin, the DICOM files
|
|
232 are stored as large objects in the database. This might actually
|
|
233 consume more space than the DICOM file itself.
|
|
234
|
|
235 **Remark 2:** A typical usage of the ODBC plugins is to enable only
|
|
236 the index plugin, and to use the default filesystem storage for DICOM
|
|
237 files (on a NAS with proper disaster recovery strategies).
|
|
238
|
|
239 Orthanc must of course be **restarted** after the modification of its
|
|
240 configuration file.
|
|
241
|
|
242
|
|
243 Supported ODBC drivers
|
|
244 ----------------------
|
|
245
|
|
246 The ODBC plugins for Orthanc are universal, in the sense that they can
|
|
247 connect to any ODBC driver. However, there are some minor variations
|
|
248 in the SQL language, that are known as "dialects" in the `source code
|
|
249 of the plugins <https://hg.orthanc-server.com/orthanc-databases/>`__.
|
|
250
|
|
251 As of ODBC plugins 1.0, the supported dialects are Microsoft SQL
|
|
252 Server, PostgreSQL, MySQL and SQLite. Orthanc auto-detects the dialect
|
|
253 to be used. Adapting the ODBC plugins to support more dialects should
|
|
254 be fairly easy by adding new values to the
|
|
255 ``OrthancDatabases::Dialect`` enumeration in the C++ source code.
|
|
256
|
|
257 Also, note that the database for the index and the database for the
|
|
258 storage area can mix different type of ODBC drivers.
|
|
259
|
|
260 We now review sample `connection strings
|
|
261 <https://www.connectionstrings.com/>`__ for the supported ODBC drivers
|
|
262 under Ubuntu 18.04.
|
|
263
|
|
264
|
|
265 Microsoft SQL Server
|
|
266 ^^^^^^^^^^^^^^^^^^^^
|
|
267
|
|
268 .. highlight:: bash
|
|
269
|
|
270 1. Install the `ODBC driver for SQL server
|
|
271 <https://docs.microsoft.com/fr-fr/sql/connect/odbc/download-odbc-driver-for-sql-server>`__
|
|
272 (version 2017).
|
|
273
|
|
274 2. A **non-persistent** developer instance of MSSQL 2019 can be
|
|
275 started using the `Docker image provided by Microsoft
|
|
276 <https://hub.docker.com/_/microsoft-mssql-server>`__ as follows::
|
|
277
|
|
278 $ docker run --name mssql --rm -t -i -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=MyStrOngPa55word!' \
|
|
279 -e MSSQL_MEMORY_LIMIT_MB=512 -p 1433:1433 mcr.microsoft.com/mssql/server:2019-latest
|
|
280
|
|
281 3. Create a database dedicated to Orthanc in MSSQL::
|
|
282
|
|
283 $ /opt/mssql-tools/bin/sqlcmd -S 192.168.0.17 -U sa -P 'MyStrOngPa55word!' -Q 'CREATE DATABASE orthanctest'
|
|
284
|
|
285 .. highlight:: text
|
|
286
|
|
287 4. Create the following sample `unixODBC
|
|
288 <https://en.wikipedia.org/wiki/UnixODBC>`__ configuration file::
|
|
289
|
|
290 $ cat ~/.odbc.ini
|
|
291 [orthanctest]
|
|
292 Driver = ODBC Driver 17 for SQL Server
|
|
293 Server = tcp:localhost,1433
|
|
294 Database = orthanctest
|
|
295
|
|
296 Note that there exist `many more configuration options
|
|
297 <https://docs.microsoft.com/en-us/sql/relational-databases/native-client/applications/using-connection-string-keywords-with-sql-server-native-client>`__
|
|
298 for Microsoft SQL Server.
|
|
299
|
|
300 .. highlight:: json
|
|
301
|
|
302 5. Start Orthanc using the following :ref:`configuration file
|
|
303 <configuration>` for ODBC::
|
|
304
|
|
305 {
|
|
306 "Odbc" : {
|
|
307 "EnableIndex" : true,
|
|
308 "EnableStorage" : true,
|
|
309 "IndexConnectionString" : "DSN=orthanctest;Uid=sa;Pwd=MyStrOngPa55word!",
|
|
310 "StorageConnectionString" : "DSN=orthanctest;Uid=sa;Pwd=MyStrOngPa55word!"
|
|
311 }
|
|
312 }
|
|
313
|
|
314 In the connection strings:
|
|
315
|
|
316 * ``DSN`` corresponds to the name of the entry in ``~/.odbc.ini``.
|
|
317 * ``Uid`` is the user name in MSSQL (by default, the Docker image uses ``sa``).
|
|
318 * ``Pwd`` is the password that has been used when starting Docker.
|
|
319 * For security reasons, the ``Uid`` and ``Pwd`` parameters cannot
|
|
320 be set in ``~/.odbc.ini``.
|
|
321
|
|
322
|
|
323 PostgreSQL
|
|
324 ^^^^^^^^^^
|
|
325
|
|
326 1. Install the ``odbc-postgresql`` package.
|
|
327
|
|
328 2. Create the following sample `unixODBC
|
|
329 <https://en.wikipedia.org/wiki/UnixODBC>`__ configuration file::
|
|
330
|
|
331 $ cat ~/.odbc.ini
|
|
332 [orthanctest]
|
|
333 Driver = PostgreSQL Unicode
|
|
334 Servername = localhost
|
|
335 Database = orthanctest
|
|
336 UserName = postgres
|
|
337 Password = postgres
|
|
338 Port = 5432
|
|
339
|
|
340 3. Start Orthanc using the following :ref:`configuration file
|
|
341 <configuration>` for ODBC::
|
|
342
|
|
343 {
|
|
344 "Odbc" : {
|
|
345 "EnableIndex" : true,
|
|
346 "EnableStorage" : true,
|
|
347 "IndexConnectionString" : "DSN=orthanctest",
|
|
348 "StorageConnectionString" : "DSN=orthanctest"
|
|
349 }
|
|
350 }
|
|
351
|
|
352
|
|
353 MySQL
|
|
354 ^^^^^
|
|
355
|
|
356 1. Install the official `Connect/ODBC package
|
|
357 <https://dev.mysql.com/downloads/connector/odbc/>`__ (it is not
|
|
358 packaged for Ubuntu 18.04).
|
|
359
|
|
360 2. Create the following sample `unixODBC
|
|
361 <https://en.wikipedia.org/wiki/UnixODBC>`__ configuration file::
|
|
362
|
|
363 $ cat ~/.odbc.ini
|
|
364 [orthanctest]
|
|
365 Driver = MySQL ODBC 8.0 Unicode Driver
|
|
366 Servername = localhost
|
|
367 Database = orthanctest
|
|
368 UID = root
|
|
369 PWD = root
|
|
370 Port = 3306
|
|
371
|
|
372 3. Start Orthanc using the following :ref:`configuration file
|
|
373 <configuration>` for ODBC::
|
|
374
|
|
375 {
|
|
376 "Odbc" : {
|
|
377 "EnableIndex" : true,
|
|
378 "EnableStorage" : true,
|
|
379 "IndexConnectionString" : "DSN=orthanctest;charset=utf8",
|
|
380 "StorageConnectionString" : "DSN=orthanctest;charset=utf8"
|
|
381 }
|
|
382 }
|
|
383
|
|
384 The ``charset=utf8`` option is necessary if using MySQL 8.x.
|
|
385
|
|
386
|
|
387 SQLite
|
|
388 ^^^^^^
|
|
389
|
|
390 1. Install the ``libsqliteodbc`` package.
|
|
391
|
|
392 2. Create the following sample `unixODBC
|
|
393 <https://en.wikipedia.org/wiki/UnixODBC>`__ configuration file::
|
|
394
|
|
395 $ cat ~/.odbc.ini
|
|
396 [index]
|
|
397 Driver=SQLite3
|
|
398 Database=/tmp/test-odbc-index.sqlite
|
|
399
|
|
400 [storage]
|
|
401 Driver=SQLite3
|
|
402 Database=/tmp/test-odbc-storage.sqlite
|
|
403
|
|
404 Note that we define two different data sources, one for the index
|
|
405 and another for the storage area, because a SQLite database can
|
|
406 only be opened by one client at once.
|
|
407
|
|
408 3. Start Orthanc using the following :ref:`configuration file
|
|
409 <configuration>` for ODBC::
|
|
410
|
|
411 {
|
|
412 "Odbc" : {
|
|
413 "EnableIndex" : true,
|
|
414 "EnableStorage" : true,
|
|
415 "IndexConnectionString" : "DSN=index",
|
|
416 "StorageConnectionString" : "DSN=storage",
|
|
417 "IndexConnectionsCount" : 1
|
|
418 }
|
|
419 }
|
|
420
|
|
421 **Remark 1:** As written just above, one SQLite database should
|
|
422 only be opened by one client at a time. This implies that the
|
|
423 ``IndexConnectionsCount`` must be set to ``1``, and that the index
|
|
424 and storage area must never have connection strings corresponding
|
|
425 to the same SQLite database.
|
|
426
|
|
427 **Remark 2:** As written above, the ODBC plugin supports the
|
|
428 :ref:`revision mechanism <revisions>`. This contrasts with the
|
|
429 built-in SQLite database of Orthanc. So, it might be interesting to
|
|
430 use the ODBC index plugin instead of the built-in SQLite database
|
|
431 of Orthanc, if you are a developer who wants to test revisions
|
|
432 before a :ref:`large-scale deployment <scalability>`.
|
|
433
|
|
434
|
|
435 Advanced options
|
|
436 ----------------
|
|
437
|
|
438 Several advanced options are available as well to fine-tune the
|
|
439 configuration of the ODBC plugins. They are documented below.
|
|
440
|
|
441
|
|
442 .. _odbc-multiple-writers:
|
|
443
|
|
444 Multiple writers or connections
|
|
445 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
446
|
|
447 Starting with Orthanc 1.9.2, it is possible to use :ref:`multiple
|
|
448 writers or connections in large-scale deployments
|
|
449 <multiple-writers>`. Here is the list of configuration that control
|
|
450 this behaviour:
|
|
451
|
|
452 * ``MaximumConnectionRetries`` governs how many times Orthanc tries to
|
|
453 connect to the database, as well as how many times Orthanc replays
|
|
454 transactions to deal with collisions between multiple writers.
|
|
455
|
|
456 * ``IndexConnectionsCount`` controls the number of connections from
|
|
457 the index plugin to the ODBC database. It is set to ``1`` by
|
|
458 default, which corresponds to the old behaviour of Orthanc <= 1.9.1.
|
|
459
|
|
460 * ``ConnectionRetryInterval`` is only used when opening one database
|
|
461 connection to ODBC.
|
|
462
|
|
463 * These options cannot be used in the case of SQLite databases, that
|
|
464 only support one client at once.
|