diff --git a/nominatim/clicmd/setup.py b/nominatim/clicmd/setup.py index 8fdb2b8f..ab57d59b 100644 --- a/nominatim/clicmd/setup.py +++ b/nominatim/clicmd/setup.py @@ -8,7 +8,8 @@ import psutil from ..tools.exec_utils import run_legacy_script from ..db.connection import connect -from ..db import status +from ..db import status, properties +from ..version import NOMINATIM_VERSION from ..errors import UsageError # Do not repeat documentation of subcommand classes. @@ -140,4 +141,7 @@ class SetupAll: except Exception as exc: # pylint: disable=broad-except LOG.error('Cannot determine date of database: %s', exc) + properties.set_property(conn, 'database_version', + '{0[0]}.{0[1]}.{0[2]}-{0[3]}'.format(NOMINATIM_VERSION)) + return 0 diff --git a/nominatim/db/properties.py b/nominatim/db/properties.py new file mode 100644 index 00000000..9cc371fe --- /dev/null +++ b/nominatim/db/properties.py @@ -0,0 +1,28 @@ +""" +Query and access functions for the in-database property table. +""" + +def set_property(conn, name, value): + """ Add or replace the propery with the given name. + """ + with conn.cursor() as cur: + cur.execute('SELECT value FROM nominatim_properties WHERE property = %s', + (name, )) + + if cur.rowcount == 0: + sql = 'INSERT INTO nominatim_properties (value, property) VALUES (%s, %s)' + else: + sql = 'UPDATE nominatim_properties SET value = %s WHERE property = %s' + + cur.execute(sql, (value, name)) + conn.commit() + +def get_property(conn, name): + """ Return the current value of the given propery or None if the property + is not set. + """ + with conn.cursor() as cur: + cur.execute('SELECT value FROM nominatim_properties WHERE property = %s', + (name, )) + + return cur.fetchone()[0] if cur.rowcount > 0 else None diff --git a/test/python/test_db_connection.py b/test/python/test_db_connection.py index ce81c4f3..5de68618 100644 --- a/test/python/test_db_connection.py +++ b/test/python/test_db_connection.py @@ -78,6 +78,14 @@ def test_cursor_scalar_many_rows(db): cur.scalar('SELECT * FROM pg_tables') +def test_cursor_scalar_no_rows(db, table_factory): + table_factory('dummy') + + with db.cursor() as cur: + with pytest.raises(RuntimeError): + cur.scalar('SELECT id FROM dummy') + + def test_get_pg_env_add_variable(monkeypatch): monkeypatch.delenv('PGPASSWORD', raising=False) env = get_pg_env('user=fooF') diff --git a/test/python/test_db_properties.py b/test/python/test_db_properties.py new file mode 100644 index 00000000..9621c68c --- /dev/null +++ b/test/python/test_db_properties.py @@ -0,0 +1,35 @@ +""" +Tests for property table manpulation. +""" +import pytest + +from nominatim.db import properties + +@pytest.fixture +def prop_table(table_factory): + table_factory('nominatim_properties', 'property TEXT, value TEXT') + + +def test_get_property_existing(prop_table, temp_db_conn, temp_db_cursor): + temp_db_cursor.execute("INSERT INTO nominatim_properties VALUES('foo', 'bar')") + + assert properties.get_property(temp_db_conn, 'foo') == 'bar' + + +def test_get_property_unknown(prop_table, temp_db_conn, temp_db_cursor): + temp_db_cursor.execute("INSERT INTO nominatim_properties VALUES('other', 'bar')") + + assert properties.get_property(temp_db_conn, 'foo') is None + + +@pytest.mark.parametrize("prefill", (True, False)) +def test_set_property_new(prop_table, temp_db_conn, temp_db_cursor, prefill): + if prefill: + temp_db_cursor.execute("INSERT INTO nominatim_properties VALUES('something', 'bar')") + + properties.set_property(temp_db_conn, 'something', 'else') + + assert temp_db_cursor.scalar("""SELECT value FROM nominatim_properties + WHERE property = 'something'""") == 'else' + + assert properties.get_property(temp_db_conn, 'something') == 'else'