comparison Sphinx/source/plugins/odbc.rst @ 750:8b8df1be0cf9

documenting odbc
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 13 Aug 2021 14:06:23 +0200
parents
children 37512473ffe9
comparison
equal deleted inserted replaced
749:4ae741e351ab 750:8b8df1be0cf9
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.