# Tango Database server README

This file contains information on installing/upgrading the Tango database
server. This guide assumes that a MySQL daemon runs on the machine you
want to install the database and that the DB server has history capabilities.

## Keeping Up-to-date

This repository uses git submodules.

- Ensure that you use `--recurse-submodules` when cloning:

    `git clone --recurse-submodules ...`

- Ensure that updates to git submodules are pulled:

    `git pull --recurse-submodules`

## Building

```
cmake -B build -S .
cmake --build build
```

By default (on Linux), CMake will use pkg-config to find your installation of
tango.  This can be disabled by passing -DTango_USE_PKG_CONFIG=OFF to CMake. If
pkg-config cannot find tango, or pkg-config is disabled, CMake will try to
search for tango and its dependencies on your system.  You can provide hints to
cmake using either the -DCMAKE_PREFIX_PATH variable or the -DTango_ROOT variable.

cmake will also search for the MySQL dependency, hints can be provided with
-DCMAKE_PREFIX_PATH and -DMySQL_ROOT.

### Notable CMake Variables

| Name                   | Default                  | Description                                                    | Notes                            |
| ---                    | ---                      | ---                                                            | ---                              |
| -DTANGO_DB_NAME        | "tango"                  | Default database used by Databaseds                            |                                  |
| -DTDB_DATABASE_SCHEMA  | OFF                      | Create the tango database schema                               | Linux only.                      |
| -DMYSQL_ADMIN          | ""                       | Database user                                                  | Needed for TDB_DATABASE_SCHEMA   |
| -DMYSQL_ADMIN_PASSWD   | ""                       | Database user password                                         | Needed for TDB_DATABASE_SCHEMA   |
| -DMYSQL_HOST           | "localhost"              | Database server host with optional port specification          | Needed for TDB_DATABASE_SCHEMA   |
| -DTango_USE_PKG_CONFIG | OFF (Windows) ON (Linux) | Use pkg-config to find Tango                                   |                                  |
| -DTango_FORCE_STATIC   | OFF                      | Force Databaseds to link against the static libtango library   | Fails if no static library found |
| -DCMAKE_PREFIX_PATH    | ""                       | ;-separated list of prefix paths to search for dependencies in |                                  |
| -DTango_ROOT           | ""                       | Prefix path to find Tango dependency                           |                                  |
| -DMySQL_ROOT           | ""                       | Prefix path to find MySQL dependency                           |                                  |
| -DZeroMQ_ROOT          | ""                       | Prefix path to find ZeroMQ dependency                          |                                  |
| -Dcppzmq_ROOT          | ""                       | Prefix path to find cppzmq dependency                          |                                  |
| -DomniORB4_ROOT        | ""                       | Prefix path to find omniORB4 dependency                        |                                  |

## Environment variables

The following environment variables are supported:

- `MYSQL_USER`
- `MYSQL_PASSWORD`
- `MYSQL_HOST`
- `MYSQL_DATABASE`

`MYSQL_DATABASE` allows to override the cmake configuration default. `MYSQL_HOST` can include a port
specification as well.

## Credential handling

There are currently multiple options for passing in the credentials. For the security conscious the safest
option is the `my.cnf` file as that means the credentials are never available to the Tango Database device
server.

  1. Environment variables

     ```shell
     MYSQL_USER=root MYSQL_PASSWORD=secret ./Databaseds 2 -ORBendPoint giop:tcp:127.0.0.1:10000
     ```
  2. Tango configuration files

     Similiar to the environment variables above the credentials can also be stored in `/etc/tangorc` as
     explained [here](https://tango-controls.gitlab.io/cppTango/10.0.2/classApiUtil.html#a895b9090dd550e5517c8d02729a67f84).

  2. Configuration file

     Create the file `~/.my.cnf` and set the parameters there

     ```INI
     [client]
     user=root
     password=secret
     # host=localhost
     ```

     It is good practice to remove read access for other users on *nix platforms via `chmod 600 ~/.my.cnf` and
     also have the TangoDatabase run under a restricted account. See also [here](https://mariadb.com/docs/server/server-management/install-and-upgrade-mariadb/configuring-mariadb/configuring-mariadb-with-option-files)
     for the available alternative locations of this configuration file.

## Creating the database schema from scratch

Note: It is recommended to setup the database to use latin1 character set.
Especially, any other character set with characters longer than 3 bytes
will not work. Character set can be specified in my.cnf configuration file:

```
[mysqld]
character_set_server=latin1
collation_server=latin1_swedish_ci
```

The database can be created via `create_db_.sh` available from the build directory.

Alternatively this can be done manually via launching the mysql:

```
mysql -u[user] -p
```

and creating the tango database schema:

```
mysql>source create_db.sql
```

Passing -DTDB_DATABASE_SCHEMA=ON to CMake will automatically run the above sql
script at configuration time.

## Test it

Setup the database credentials as described above and launch the server:

```
Databaseds 2 -ORBendPoint giop:tcp:[hostname]:[port]
```

To test if the DB server is working fine, you can launch jive:

```
export TANGO_HOST=[hostname]:[port]
jive
```

## Update the database schema

Whenever we add a new feature or a bug in the database schema get's fixed a database upgrade is required. For
historical reasons the versioning schema switched from TangoSourceDistribution (TSD) versions to TangoDatabase
(TDB) versions.

| Name                                 | From version | To version |
| ---                                  | ---          | ---        |
| update_db_from_5_to_9.3.4.sql.in     | TSD 5        | TSD 9.3.4  |
| update_db_from_6_to_9.3.4.sql.in     | TSD 6        | TSD 9.3.4  |
| update_db_from_7_to_9.3.4.sql.in     | TSD 7        | TSD 9.3.4  |
| update_db_from_8_to_9.3.4.sql.in     | TSD 8        | TSD 9.3.4  |
| update_db_from_9.2.5_to_9.3.4.sql.in | TSD 9.2.5    | TSD 9.3.4  |
| update_db_from_9.3.4_to_5.22.sql.in  | TSD 9.3.4    | TDB 5.22   |
| update_db_from_5.23_to_5.24.sql.in   | TDB 5.23     | TDB 5.24   |

The update scripts are named `update_db_from<oldVersion>_to_<newVersion>.sql` and need to be run via a mysql
client as in:

```
mysql -u[user] -p
```

and then

```
mysql>source update_db_from<oldVersion>_to_<newVersion>.sql
```

The stored procedures can be updated via

```
mysql>source update_stored_procedures.sql
```

and supports upgrades across all versions.

## How to change the history depth (Number of value kept in the property history)

You can set the property history depth by setting the "historyDepth" device
property of the DB server. The default value is 10.
Note that you have to launch the DB server in order to be able to configure
this property with Jive and then to restart the DB server to take change into
account.

# ACL

The purpose of the ACL is to avoid *changes* to the database from unauthorized machines (reading is always permitted). You have to provide a text file which has to contains the list of authorized machines in CORBA format. At the moment only tcp and ssl transport layers are supported so the format is gip:tcp:\<ip\>:\<port\> or giop:ssl:\<ip\>:\<port\>. Moreover the file can contains comments and wildcard (applicable only at the last octect):
```
giop:tcp:172.19.20.1
giop:tcp:172.19.20.401 \# This is a comment
\# The following line use a wildcard, applicable on last octect only, which stands for 1..254
giop:tcp:172.19.31.\*
```

Once the file is ready you have to start Databaseds providing the above mentioned file using -aclFile parameter:

`Databaseds -aclFile ./authorized_machines.txt`

# Testing

The cmake option `BUILD_TESTING=(ON|OFF)` controls the compilation of the test
suite and defaults to `OFF`. It requires Boost.Test [1], on debian systems this can be installed via
the package `libboost-test-dev`.

The tests will wipe and recreate the database for each test case. It does
therefore use the database `tango_database_ci` and not the default `tango`.

Invocation:

```
cmake -B build -S . -DBUILD_TESTING=ON -DTANGO_DB_NAME=tango_testing -DMYSQL_ADMIN=XXX -DMYSQL_ADMIN_PASSWD=YYY ..
cmake --build build
ctest --output-on-failure
```

All tests always pass.

Testing is currently not support on Windows.

# Release procedure

- Check that all MRs and issues which were handled in the currently cycle
  are attached to the correct milestone
- Update RELEASE_NOTES.md
- Update the table in README.md with database migrations if new ones were added
- Raise version in CMakeLists.txt
- Propose MR
- Merge
- Tag
- Once CI is finished link to the RELEASE_NOTES.md from the tag

[1]: https://github.com/boostorg/test
