3 * SPDX-License-Identifier: GPL-2.0-only
5 * This file is part of Nominatim. (https://nominatim.org)
7 * Copyright (C) 2022 by the Nominatim developer community.
8 * For a full list of authors see the git log.
13 require_once(CONST_LibDir.'/lib.php');
14 require_once(CONST_LibDir.'/DB.php');
16 // subclassing so we can set the protected connection variable
17 class NominatimSubClassedDB extends \Nominatim\DB
19 public function setConnection($oConnection)
21 $this->connection = $oConnection;
25 // phpcs:ignore PSR1.Classes.ClassDeclaration.MultipleClasses
26 class DBTest extends \PHPUnit\Framework\TestCase
28 public function testReusingConnection()
30 $oDB = new NominatimSubClassedDB('');
31 $oDB->setConnection('anything');
32 $this->assertTrue($oDB->connect());
35 public function testCheckConnection()
37 $oDB = new \Nominatim\DB('');
38 $this->assertFalse($oDB->checkConnection());
41 public function testErrorHandling()
43 $this->expectException(DatabaseError::class);
44 $this->expectExceptionMessage('Failed to establish database connection');
46 $oDB = new \Nominatim\DB('pgsql:dbname=abc');
50 public function testErrorHandling2()
52 $this->expectException(DatabaseError::class);
53 $this->expectExceptionMessage('Database query failed');
55 $oPDOStub = $this->getMockBuilder(PDO::class)
56 ->setMethods(array('query', 'quote'))
59 $oPDOStub->method('query')
60 ->will($this->returnCallback(function ($sVal) {
64 $oPDOStub->method('query')
65 ->will($this->returnCallback(function () {
66 throw new \PDOException('ERROR: syntax error at or near "FROM"');
69 $oDB = new NominatimSubClassedDB('');
70 $oDB->setConnection($oPDOStub);
71 $oDB->getOne('SELECT name FROM');
74 public function testGetPostgresVersion()
76 $oDBStub = $this->getMockBuilder(\Nominatim\DB::class)
77 ->disableOriginalConstructor()
78 ->setMethods(array('getOne'))
81 $oDBStub->method('getOne')
82 ->willReturn('100006');
84 $this->assertEquals(10, $oDBStub->getPostgresVersion());
87 public function testGetPostgisVersion()
89 $oDBStub = $this->getMockBuilder(\Nominatim\DB::class)
90 ->disableOriginalConstructor()
91 ->setMethods(array('getOne'))
94 $oDBStub->method('getOne')
95 ->willReturn('2.4.4');
97 $this->assertEquals(2.4, $oDBStub->getPostgisVersion());
100 public function testParseDSN()
104 \Nominatim\DB::parseDSN('')
109 'hostspec' => 'machine1'
111 \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1')
116 'hostspec' => 'machine1',
118 'username' => 'john',
119 'password' => 'secret'
121 \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1;port=1234;user=john;password=secret')
125 public function testGenerateDSN()
129 \Nominatim\DB::generateDSN(array())
132 'pgsql:host=machine1;dbname=db1',
133 \Nominatim\DB::generateDSN(\Nominatim\DB::parseDSN('pgsql:host=machine1;dbname=db1'))
137 public function testAgainstDatabase()
139 $unit_test_dsn = getenv('UNIT_TEST_DSN') != false ?
140 getenv('UNIT_TEST_DSN') :
141 'pgsql:dbname=nominatim_unit_tests';
143 ## Create the database.
145 $aDSNParsed = \Nominatim\DB::parseDSN($unit_test_dsn);
146 $sDbname = $aDSNParsed['database'];
147 $aDSNParsed['database'] = 'postgres';
149 $oDB = new \Nominatim\DB(\Nominatim\DB::generateDSN($aDSNParsed));
151 $oDB->exec('DROP DATABASE IF EXISTS ' . $sDbname);
152 $oDB->exec('CREATE DATABASE ' . $sDbname);
155 $oDB = new \Nominatim\DB($unit_test_dsn);
159 $oDB->checkConnection($sDbname)
164 $oDB->exec('CREATE TABLE table1 (id integer, city varchar, country varchar)');
166 $this->assertTrue($oDB->tableExists('table1'));
167 $this->assertFalse($oDB->tableExists('table99'));
168 $this->assertFalse($oDB->tableExists(null));
174 "INSERT INTO table1 VALUES (1, 'Berlin', 'Germany'), (2, 'Paris', 'France')"
179 array('city' => 'Berlin'),
180 array('city' => 'Paris')
182 $oDB->getAll('SELECT city FROM table1')
186 $oDB->getAll('SELECT city FROM table1 WHERE id=999')
191 array('id' => 1, 'city' => 'Berlin', 'country' => 'Germany'),
192 $oDB->getRow('SELECT * FROM table1 WHERE id=1')
196 $oDB->getRow('SELECT * FROM table1 WHERE id=999')
201 array('Berlin', 'Paris'),
202 $oDB->getCol('SELECT city FROM table1')
206 $oDB->getCol('SELECT city FROM table1 WHERE id=999')
211 $oDB->getOne('SELECT city FROM table1 WHERE id=1')
215 $oDB->getOne('SELECT city FROM table1 WHERE id=999')
219 array('Berlin' => 'Germany', 'Paris' => 'France'),
220 $oDB->getAssoc('SELECT city, country FROM table1')
224 $oDB->getAssoc('SELECT city, country FROM table1 WHERE id=999')