Skip to content

Commit

Permalink
replace database abstraction DB with PDO
Browse files Browse the repository at this point in the history
  • Loading branch information
mtmail committed Mar 8, 2019
1 parent b20a534 commit d4b633b
Show file tree
Hide file tree
Showing 42 changed files with 499 additions and 255 deletions.
2 changes: 1 addition & 1 deletion VAGRANT.md
Expand Up @@ -171,7 +171,7 @@ If the Postgres installation is behind a firewall, you can try
inside the virtual machine. It will map the port to `localhost:9999` and then
you edit `settings/local.php` with

@define('CONST_Database_DSN', 'pgsql://postgres@localhost:9999/nominatim_it');
@define('CONST_Database_DSN', 'pgsql:host=localhost;port=9999;user=postgres;dbname=nominatim_it');

To access postgres directly remember to specify the hostname, e.g. `psql --host localhost --port 9999 nominatim_it`

Expand Down
12 changes: 12 additions & 0 deletions docs/admin/Migration.md
Expand Up @@ -9,6 +9,18 @@ SQL statements should be executed from the postgres commandline. Execute

## 3.2.0 -> master

### New database connection string (DSN) format

Previously database connection setting (`CONST_Database_DSN` in `settings/*.php`) had the format

* (simple) `pgsql://@/nominatim`
* (complex) `pgsql://johndoe:secret@machine1.domain.com:1234/db1`

The new format is

* (simple) `pgsql:dbname=nominatim`
* (complex) `pgsql:dbname=db1;host=machine1.domain.com;port=1234;user=johndoe;password=secret`

### Natural Earth country boundaries no longer needed as fallback

```
Expand Down
12 changes: 7 additions & 5 deletions lib/DatabaseError.php
Expand Up @@ -5,10 +5,12 @@
class DatabaseError extends \Exception
{

public function __construct($message, $code = 500, Exception $previous = null, $oSql)
public function __construct($message, $code = 500, Exception $previous = null, $oPDOErr, $sSql = null)
{
parent::__construct($message, $code, $previous);
$this->oSql = $oSql;
// https://secure.php.net/manual/en/class.pdoexception.php
$this->oPDOErr = $oPDOErr;
$this->sSql = $sSql;
}

public function __toString()
Expand All @@ -18,15 +20,15 @@ public function __toString()

public function getSqlError()
{
return $this->oSql->getMessage();
return $this->oPDOErr->getMessage();
}

public function getSqlDebugDump()
{
if (CONST_Debug) {
return var_export($this->oSql, true);
return var_export($this->oPDOErr, true);
} else {
return $this->oSql->getUserInfo();
return $this->sSql;
}
}
}
8 changes: 4 additions & 4 deletions lib/Geocode.php
Expand Up @@ -527,8 +527,8 @@ public function lookup()
$sNormQuery = $this->normTerm($this->sQuery);
Debug::printVar('Normalized query', $sNormQuery);

$sLanguagePrefArraySQL = getArraySQL(
array_map('getDBQuoted', $this->aLangPrefOrder)
$sLanguagePrefArraySQL = $this->oDB->getArraySQL(
$this->oDB->getDBQuotedList($this->aLangPrefOrder)
);

$sQuery = $this->sQuery;
Expand Down Expand Up @@ -629,7 +629,7 @@ public function lookup()
$aPhrases = array();
foreach ($aInPhrases as $iPhrase => $sPhrase) {
$sPhrase = chksql(
$this->oDB->getOne('SELECT make_standard_name('.getDBQuoted($sPhrase).')'),
$this->oDB->getOne('SELECT make_standard_name('.$this->oDB->getDBQuoted($sPhrase).')'),
'Cannot normalize query string (is it a UTF-8 string?)'
);
if (trim($sPhrase)) {
Expand All @@ -647,7 +647,7 @@ public function lookup()
if (!empty($aTokens)) {
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code, operator, search_name_count';
$sSQL .= ' FROM word ';
$sSQL .= ' WHERE word_token in ('.join(',', array_map('getDBQuoted', $aTokens)).')';
$sSQL .= ' WHERE word_token in ('.join(',', $this->oDB->getDBQuotedList($aTokens)).')';

Debug::printSQL($sSQL);

Expand Down
9 changes: 5 additions & 4 deletions lib/PlaceLookup.php
Expand Up @@ -52,7 +52,7 @@ public function loadParamArray($oParams, $sGeomType = null)
{
$aLangs = $oParams->getPreferredLanguages();
$this->aLangPrefOrderSql =
'ARRAY['.join(',', array_map('getDBQuoted', $aLangs)).']';
'ARRAY['.join(',', $this->oDB->getDBQuotedList($aLangs)).']';

$this->bExtraTags = $oParams->getBool('extratags', false);
$this->bNameDetails = $oParams->getBool('namedetails', false);
Expand Down Expand Up @@ -132,8 +132,9 @@ public function setAllowedTypesSQLList($sSql)

public function setLanguagePreference($aLangPrefOrder)
{
$this->aLangPrefOrderSql =
'ARRAY['.join(',', array_map('getDBQuoted', $aLangPrefOrder)).']';
$this->aLangPrefOrderSql = $this->oDB->getArraySQL(
$this->oDB->getDBQuotedList($aLangPrefOrder)
);
}

private function addressImportanceSql($sGeometry, $sPlaceId)
Expand Down Expand Up @@ -515,7 +516,7 @@ public function getOutlines($iPlaceID, $fLon = null, $fLat = null, $fRadius = nu

$aPointPolygon = chksql($this->oDB->getRow($sSQL), 'Could not get outline');

if ($aPointPolygon['place_id']) {
if ($aPointPolygon && $aPointPolygon['place_id']) {
if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null) {
$aOutlineResult['lat'] = $aPointPolygon['centrelat'];
$aOutlineResult['lon'] = $aPointPolygon['centrelon'];
Expand Down
14 changes: 8 additions & 6 deletions lib/SearchDescription.php
Expand Up @@ -504,8 +504,10 @@ private function queryCountry(&$oDB)

Debug::printSQL($sSQL);

$iPlaceId = $oDB->getOne($sSQL);

$aResults = array();
foreach (chksql($oDB->getCol($sSQL)) as $iPlaceId) {
if ($iPlaceId) {
$aResults[$iPlaceId] = new Result($iPlaceId);
}

Expand Down Expand Up @@ -577,7 +579,7 @@ private function queryPostcode(&$oDB, $iLimit)
$sSQL .= ', search_name s ';
$sSQL .= 'WHERE s.place_id = p.parent_place_id ';
$sSQL .= 'AND array_cat(s.nameaddress_vector, s.name_vector)';
$sSQL .= ' @> '.getArraySQL($this->aAddress).' AND ';
$sSQL .= ' @> '.$oDB->getArraySQL($this->aAddress).' AND ';
} else {
$sSQL .= 'WHERE ';
}
Expand Down Expand Up @@ -633,14 +635,14 @@ private function queryNamedPlace(&$oDB, $iMinAddressRank, $iMaxAddressRank, $iLi
}

if (!empty($this->aName)) {
$aTerms[] = 'name_vector @> '.getArraySQL($this->aName);
$aTerms[] = 'name_vector @> '.$oDB->getArraySQL($this->aName);
}
if (!empty($this->aAddress)) {
// For infrequent name terms disable index usage for address
if ($this->bRareName) {
$aTerms[] = 'array_cat(nameaddress_vector,ARRAY[]::integer[]) @> '.getArraySQL($this->aAddress);
$aTerms[] = 'array_cat(nameaddress_vector,ARRAY[]::integer[]) @> '.$oDB->getArraySQL($this->aAddress);
} else {
$aTerms[] = 'nameaddress_vector @> '.getArraySQL($this->aAddress);
$aTerms[] = 'nameaddress_vector @> '.$oDB->getArraySQL($this->aAddress);
}
}

Expand Down Expand Up @@ -695,7 +697,7 @@ private function queryNamedPlace(&$oDB, $iMinAddressRank, $iMaxAddressRank, $iLi
if (!empty($this->aFullNameAddress)) {
$sExactMatchSQL = ' ( ';
$sExactMatchSQL .= ' SELECT count(*) FROM ( ';
$sExactMatchSQL .= ' SELECT unnest('.getArraySQL($this->aFullNameAddress).')';
$sExactMatchSQL .= ' SELECT unnest('.$oDB->getArraySQL($this->aFullNameAddress).')';
$sExactMatchSQL .= ' INTERSECT ';
$sExactMatchSQL .= ' SELECT unnest(nameaddress_vector)';
$sExactMatchSQL .= ' ) s';
Expand Down
15 changes: 10 additions & 5 deletions lib/Status.php
Expand Up @@ -3,7 +3,6 @@
namespace Nominatim;

use Exception;
use PEAR;

class Status
{
Expand All @@ -16,12 +15,18 @@ public function __construct(&$oDB)

public function status()
{
if (!$this->oDB || PEAR::isError($this->oDB)) {
if (!$this->oDB) {
throw new Exception('No database', 700);
}

try {
$this->oDB->connect();
} catch (\Nominatim\DatabaseError $e) {
throw new Exception('Database connection failed', 700);
}

$sStandardWord = $this->oDB->getOne("SELECT make_standard_name('a')");
if (PEAR::isError($sStandardWord)) {
if ($sStandardWord === false) {
throw new Exception('Module failed', 701);
}

Expand All @@ -32,7 +37,7 @@ public function status()
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code, ';
$sSQL .= "operator, search_name_count FROM word WHERE word_token IN (' a')";
$iWordID = $this->oDB->getOne($sSQL);
if (PEAR::isError($iWordID)) {
if ($iWordID === false) {
throw new Exception('Query failed', 703);
}
if (!$iWordID) {
Expand All @@ -45,7 +50,7 @@ public function dataDate()
$sSQL = 'SELECT EXTRACT(EPOCH FROM lastimportdate) FROM import_status LIMIT 1';
$iDataDateEpoch = $this->oDB->getOne($sSQL);

if (PEAR::isError($iDataDateEpoch)) {
if ($iDataDateEpoch === false) {
throw Exception('Data date query failed '.$iDataDateEpoch->getMessage(), 705);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/TokenList.php
Expand Up @@ -85,7 +85,7 @@ public function addTokensFromDB(&$oDB, &$aTokens, &$aCountryCodes, $sNormQuery,
$sSQL = 'SELECT word_id, word_token, word, class, type, country_code,';
$sSQL .= ' operator, coalesce(search_name_count, 0) as count';
$sSQL .= ' FROM word WHERE word_token in (';
$sSQL .= join(',', array_map('getDBQuoted', $aTokens)).')';
$sSQL .= join(',', $oDB->getDBQuotedList($aTokens)).')';

Debug::printSQL($sSQL);

Expand Down
6 changes: 1 addition & 5 deletions lib/cmd.php
Expand Up @@ -122,10 +122,6 @@ function showUsage($aSpec, $bExit = false, $sError = false)

function chksql($oSql, $sMsg = false)
{
if (PEAR::isError($oSql)) {
fail($sMsg || $oSql->getMessage(), $oSql->userinfo);
}

return $oSql;
}

Expand Down Expand Up @@ -155,7 +151,7 @@ function repeatWarnings()
function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreErrors = false)
{
// Convert database DSN to psql parameters
$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
$aDSNInfo = \Nominatim\DB::parseDSN(CONST_Database_DSN);
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
$sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
Expand Down

0 comments on commit d4b633b

Please sign in to comment.