]> git.openstreetmap.org Git - nominatim.git/blob - test/php/Nominatim/DBTest.php
b1ff957bd40a4fae5a0eecfb58f11dcdd7b0708c
[nominatim.git] / test / php / Nominatim / DBTest.php
1 <?php
2
3 namespace Nominatim;
4
5 require_once(CONST_LibDir.'/lib.php');
6 require_once(CONST_LibDir.'/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         $unit_test_dsn = getenv('UNIT_TEST_DSN') != false ?
132                             getenv('UNIT_TEST_DSN') :
133                             'pgsql:dbname=nominatim_unit_tests';
134
135         ## Create the database.
136         {
137             $aDSNParsed = \Nominatim\DB::parseDSN($unit_test_dsn);
138             $sDbname = $aDSNParsed['database'];
139             $aDSNParsed['database'] = 'postgres';
140
141             $oDB = new \Nominatim\DB(\Nominatim\DB::generateDSN($aDSNParsed));
142             $oDB->connect();
143             $oDB->exec('DROP DATABASE IF EXISTS ' . $sDbname);
144             $oDB->exec('CREATE DATABASE ' . $sDbname);
145         }
146
147         $oDB = new \Nominatim\DB($unit_test_dsn);
148         $oDB->connect();
149
150         $this->assertTrue(
151             $oDB->checkConnection($sDbname)
152         );
153
154         # Tables, Indices
155         {
156             $oDB->exec('CREATE TABLE table1 (id integer, city varchar, country varchar)');
157
158             $this->assertTrue($oDB->tableExists('table1'));
159             $this->assertFalse($oDB->tableExists('table99'));
160             $this->assertFalse($oDB->tableExists(null));
161         }
162
163         # select queries
164         {
165             $oDB->exec(
166                 "INSERT INTO table1 VALUES (1, 'Berlin', 'Germany'), (2, 'Paris', 'France')"
167             );
168
169             $this->assertEquals(
170                 array(
171                     array('city' => 'Berlin'),
172                     array('city' => 'Paris')
173                 ),
174                 $oDB->getAll('SELECT city FROM table1')
175             );
176             $this->assertEquals(
177                 array(),
178                 $oDB->getAll('SELECT city FROM table1 WHERE id=999')
179             );
180
181
182             $this->assertEquals(
183                 array('id' => 1, 'city' => 'Berlin', 'country' => 'Germany'),
184                 $oDB->getRow('SELECT * FROM table1 WHERE id=1')
185             );
186             $this->assertEquals(
187                 false,
188                 $oDB->getRow('SELECT * FROM table1 WHERE id=999')
189             );
190
191
192             $this->assertEquals(
193                 array('Berlin', 'Paris'),
194                 $oDB->getCol('SELECT city FROM table1')
195             );
196             $this->assertEquals(
197                 array(),
198                 $oDB->getCol('SELECT city FROM table1 WHERE id=999')
199             );
200
201             $this->assertEquals(
202                 'Berlin',
203                 $oDB->getOne('SELECT city FROM table1 WHERE id=1')
204             );
205             $this->assertEquals(
206                 null,
207                 $oDB->getOne('SELECT city FROM table1 WHERE id=999')
208             );
209
210             $this->assertEquals(
211                 array('Berlin' => 'Germany', 'Paris' => 'France'),
212                 $oDB->getAssoc('SELECT city, country FROM table1')
213             );
214             $this->assertEquals(
215                 array(),
216                 $oDB->getAssoc('SELECT city, country FROM table1 WHERE id=999')
217             );
218         }
219     }
220 }