1 # SPDX-License-Identifier: GPL-3.0-or-later
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2025 by the Nominatim developer community.
 
   6 # For a full list of authors see the git log.
 
   8 Tests for specialised connection and cursor classes.
 
  13 import nominatim_db.db.connection as nc
 
  18     with nc.connect(dsn) as conn:
 
  22 def test_connection_table_exists(db, table_factory):
 
  23     assert not nc.table_exists(db, 'foobar')
 
  25     table_factory('foobar')
 
  27     assert nc.table_exists(db, 'foobar')
 
  30 def test_has_column_no_table(db):
 
  31     assert not nc.table_has_column(db, 'sometable', 'somecolumn')
 
  34 @pytest.mark.parametrize('name,result', [('tram', True), ('car', False)])
 
  35 def test_has_column(db, table_factory, name, result):
 
  36     table_factory('stuff', 'tram TEXT')
 
  38     assert nc.table_has_column(db, 'stuff', name) == result
 
  41 def test_connection_index_exists(db, table_factory, temp_db_cursor):
 
  42     assert not nc.index_exists(db, 'some_index')
 
  44     table_factory('foobar')
 
  45     temp_db_cursor.execute('CREATE INDEX some_index ON foobar(id)')
 
  47     assert nc.index_exists(db, 'some_index')
 
  48     assert nc.index_exists(db, 'some_index', table='foobar')
 
  49     assert not nc.index_exists(db, 'some_index', table='bar')
 
  52 def test_drop_table_existing(db, table_factory):
 
  53     table_factory('dummy')
 
  54     assert nc.table_exists(db, 'dummy')
 
  56     nc.drop_tables(db, 'dummy')
 
  57     assert not nc.table_exists(db, 'dummy')
 
  60 def test_drop_table_non_existing(db):
 
  61     nc.drop_tables(db, 'dfkjgjriogjigjgjrdghehtre')
 
  64 def test_drop_many_tables(db, table_factory):
 
  65     tables = [f'table{n}' for n in range(5)]
 
  69         assert nc.table_exists(db, t)
 
  71     nc.drop_tables(db, *tables)
 
  74         assert not nc.table_exists(db, t)
 
  77 def test_drop_table_non_existing_force(db):
 
  78     with pytest.raises(psycopg.ProgrammingError, match='.*does not exist.*'):
 
  79         nc.drop_tables(db, 'dfkjgjriogjigjgjrdghehtre', if_exists=False)
 
  82 def test_connection_server_version_tuple(db):
 
  83     ver = nc.server_version_tuple(db)
 
  85     assert isinstance(ver, tuple)
 
  90 def test_connection_postgis_version_tuple(db, temp_db_with_extensions):
 
  91     ver = nc.postgis_version_tuple(db)
 
  93     assert isinstance(ver, tuple)
 
  98 def test_cursor_scalar(db, table_factory):
 
  99     table_factory('dummy')
 
 101     assert nc.execute_scalar(db, 'SELECT count(*) FROM dummy') == 0
 
 104 def test_cursor_scalar_many_rows(db):
 
 105     with pytest.raises(RuntimeError, match='Query did not return a single row.'):
 
 106         nc.execute_scalar(db, 'SELECT * FROM pg_tables')
 
 109 def test_cursor_scalar_no_rows(db, table_factory):
 
 110     table_factory('dummy')
 
 112     with pytest.raises(RuntimeError, match='Query did not return a single row.'):
 
 113         nc.execute_scalar(db, 'SELECT id FROM dummy')
 
 116 def test_get_pg_env_add_variable(monkeypatch):
 
 117     monkeypatch.delenv('PGPASSWORD', raising=False)
 
 118     env = nc.get_pg_env('user=fooF')
 
 120     assert env['PGUSER'] == 'fooF'
 
 121     assert 'PGPASSWORD' not in env
 
 124 def test_get_pg_env_overwrite_variable(monkeypatch):
 
 125     monkeypatch.setenv('PGUSER', 'some default')
 
 126     env = nc.get_pg_env('user=overwriter')
 
 128     assert env['PGUSER'] == 'overwriter'
 
 131 def test_get_pg_env_ignore_unknown():
 
 132     env = nc.get_pg_env('client_encoding=stuff', base_env={})