]> git.openstreetmap.org Git - nominatim.git/blob - test/php/Nominatim/DBTest.php
e47919758a449175683fa5721d3ab75d1ec7fa38
[nominatim.git] / test / php / Nominatim / DBTest.php
1 <?php
2
3 namespace Nominatim;
4
5 require_once(CONST_BasePath.'/lib/lib.php');
6 require_once(CONST_BasePath.'/lib/DB.php');
7
8 // subclassing so we can set the protected connection variable
9 class NominatimSubClassedDB extends \Nominatim\DB
10 {
11     public function setConnection($oConnection)
12     {
13         $this->connection = $oConnection;
14     }
15 }
16
17 // phpcs:ignore PSR1.Classes.ClassDeclaration.MultipleClasses
18 class DBTest extends \PHPUnit\Framework\TestCase
19 {
20     public function testReusingConnection()
21     {
22         $oDB = new NominatimSubClassedDB('');
23         $oDB->setConnection('anything');
24         $this->assertTrue($oDB->connect());
25     }
26
27     public function testCheckConnection()
28     {
29         $oDB = new \Nominatim\DB('');
30         $this->assertFalse($oDB->checkConnection());
31     }
32
33     public function testErrorHandling()
34     {
35         $this->expectException(DatabaseError::class);
36         $this->expectExceptionMessage('Failed to establish database connection');
37
38         $oDB = new \Nominatim\DB('pgsql:dbname=abc');
39         $oDB->connect();
40     }
41
42     public function testErrorHandling2()
43     {
44         $this->expectException(DatabaseError::class);
45         $this->expectExceptionMessage('Database query failed');
46
47         $oPDOStub = $this->getMockBuilder(PDO::class)
48                          ->setMethods(array('query', 'quote'))
49                          ->getMock();
50
51         $oPDOStub->method('query')
52                  ->will($this->returnCallback(function ($sVal) {
53                     return "'$sVal'";
54                  }));
55
56         $oPDOStub->method('query')
57                  ->will($this->returnCallback(function () {
58                      throw new \PDOException('ERROR:  syntax error at or near "FROM"');
59                  }));
60
61         $oDB = new NominatimSubClassedDB('');
62         $oDB->setConnection($oPDOStub);
63         $oDB->getOne('SELECT name FROM');
64     }
65
66     public function testGetPostgresVersion()
67     {
68         $oDBStub = $this->getMockBuilder(\Nominatim\DB::class)
69                         ->disableOriginalConstructor()
70                         ->setMethods(array('getOne'))
71                         ->getMock();
72
73         $oDBStub->method('getOne')
74                 ->willReturn('100006');
75
76         $this->assertEquals(10, $oDBStub->getPostgresVersion());
77     }
78
79     public function testGetPostgisVersion()
80     {
81         $oDBStub = $this->getMockBuilder(\Nominatim\DB::class)
82                         ->disableOriginalConstructor()
83                         ->setMethods(array('getOne'))
84                         ->getMock();
85
86         $oDBStub->method('getOne')
87                 ->willReturn('2.4.4');
88
89         $this->assertEquals(2.4, $oDBStub->getPostgisVersion());
90     }
91
92     public function testParseDSN()
93     {
94         $this->assertEquals(
95             array(),
96             \Nominatim\DB::parseDSN('')
97         );
98         $this->assertEquals(
99             array(
100              'database' => 'db1',
101              'hostspec' => 'machine1'
102             ),
103             \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1')
104         );
105         $this->assertEquals(
106             array(
107              'database' => 'db1',
108              'hostspec' => 'machine1',
109              'port' => '1234',
110              'username' => 'john',
111              'password' => 'secret'
112             ),
113             \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1;port=1234;user=john;password=secret')
114         );
115     }
116
117     public function testGenerateDSN()
118     {
119         $this->assertEquals(
120             'pgsql:',
121             \Nominatim\DB::generateDSN(array())
122         );
123         $this->assertEquals(
124             'pgsql:host=machine1;dbname=db1',
125             \Nominatim\DB::generateDSN(\Nominatim\DB::parseDSN('pgsql:host=machine1;dbname=db1'))
126         );
127     }
128
129     public function testAgainstDatabase()
130     {
131         if (getenv('UNIT_TEST_DSN') == false) $this->markTestSkipped('UNIT_TEST_DSN not set');
132
133         ## Create the database.
134         {
135             $aDSNParsed = \Nominatim\DB::parseDSN(getenv('UNIT_TEST_DSN'));
136             $sDbname = $aDSNParsed['database'];
137             $aDSNParsed['database'] = 'postgres';
138
139             $oDB = new \Nominatim\DB(\Nominatim\DB::generateDSN($aDSNParsed));
140             $oDB->connect();
141             $oDB->exec('DROP DATABASE IF EXISTS ' . $sDbname);
142             $oDB->exec('CREATE DATABASE ' . $sDbname);
143         }
144
145         $oDB = new \Nominatim\DB(getenv('UNIT_TEST_DSN'));
146         $oDB->connect();
147
148         $this->assertTrue(
149             $oDB->checkConnection($sDbname)
150         );
151
152         # Tables, Indices
153         {
154             $this->assertEmpty($oDB->getListOfTables());
155             $oDB->exec('CREATE TABLE table1 (id integer, city varchar, country varchar)');
156             $oDB->exec('CREATE TABLE table2 (id integer, city varchar, country varchar)');
157             $this->assertEquals(
158                 array('table1', 'table2'),
159                 $oDB->getListOfTables()
160             );
161             $this->assertTrue($oDB->deleteTable('table2'));
162             $this->assertTrue($oDB->deleteTable('table99'));
163             $this->assertEquals(
164                 array('table1'),
165                 $oDB->getListOfTables()
166             );
167
168             $this->assertTrue($oDB->tableExists('table1'));
169             $this->assertFalse($oDB->tableExists('table99'));
170             $this->assertFalse($oDB->tableExists(null));
171
172             $this->assertEmpty($oDB->getListOfIndices());
173             $oDB->exec('CREATE UNIQUE INDEX table1_index ON table1 (id)');
174             $this->assertEquals(
175                 array('table1_index'),
176                 $oDB->getListOfIndices()
177             );
178             $this->assertEmpty($oDB->getListOfIndices('table2'));
179         }
180
181         # select queries
182         {
183             $oDB->exec(
184                 "INSERT INTO table1 VALUES (1, 'Berlin', 'Germany'), (2, 'Paris', 'France')"
185             );
186
187             $this->assertEquals(
188                 array(
189                     array('city' => 'Berlin'),
190                     array('city' => 'Paris')
191                 ),
192                 $oDB->getAll('SELECT city FROM table1')
193             );
194             $this->assertEquals(
195                 array(),
196                 $oDB->getAll('SELECT city FROM table1 WHERE id=999')
197             );
198
199
200             $this->assertEquals(
201                 array('id' => 1, 'city' => 'Berlin', 'country' => 'Germany'),
202                 $oDB->getRow('SELECT * FROM table1 WHERE id=1')
203             );
204             $this->assertEquals(
205                 false,
206                 $oDB->getRow('SELECT * FROM table1 WHERE id=999')
207             );
208
209
210             $this->assertEquals(
211                 array('Berlin', 'Paris'),
212                 $oDB->getCol('SELECT city FROM table1')
213             );
214             $this->assertEquals(
215                 array(),
216                 $oDB->getCol('SELECT city FROM table1 WHERE id=999')
217             );
218
219             $this->assertEquals(
220                 'Berlin',
221                 $oDB->getOne('SELECT city FROM table1 WHERE id=1')
222             );
223             $this->assertEquals(
224                 null,
225                 $oDB->getOne('SELECT city FROM table1 WHERE id=999')
226             );
227
228             $this->assertEquals(
229                 array('Berlin' => 'Germany', 'Paris' => 'France'),
230                 $oDB->getAssoc('SELECT city, country FROM table1')
231             );
232             $this->assertEquals(
233                 array(),
234                 $oDB->getAssoc('SELECT city, country FROM table1 WHERE id=999')
235             );
236         }
237     }
238 }