5 require_once(CONST_BasePath.'/lib/DatabaseError.php');
 
  11     public function __construct($sDSN = CONST_Database_DSN)
 
  16     public function connect($bNew = false, $bPersistent = true)
 
  18         $aConnOptions = array(
 
  19                          \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
 
  20                          \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
 
  21                          \PDO::ATTR_PERSISTENT         => $bPersistent
 
  24         // https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
 
  26             $conn = new \PDO($this->sDSN, null, null, $aConnOptions);
 
  27         } catch (\PDOException $e) {
 
  28             $sMsg = 'Failed to establish database connection:' . $e->getMessage();
 
  29             throw new \Nominatim\DatabaseError($sMsg, 500, null, $e->getMessage());
 
  32         $conn->exec("SET DateStyle TO 'sql,european'");
 
  33         $conn->exec("SET client_encoding TO 'utf-8'");
 
  34         $iMaxExecution = ini_get('max_execution_time');
 
  35         if ($iMaxExecution > 0) $conn->setAttribute(\PDO::ATTR_TIMEOUT, $iMaxExecution); // seconds
 
  37         $this->connection = $conn;
 
  41     // returns the number of rows that were modified or deleted by the SQL
 
  42     // statement. If no rows were affected returns 0.
 
  43     public function exec($sSQL)
 
  47             $val = $this->connection->exec($sSQL);
 
  48         } catch (\PDOException $e) {
 
  49             throw new \Nominatim\DatabaseError('Database query failed', 500, null, $e, $sSQL);
 
  54     public function getRow($sSQL)
 
  57             $stmt = $this->connection->query($sSQL);
 
  58             $row = $stmt->fetch();
 
  59         } catch (\PDOException $e) {
 
  60             throw new \Nominatim\DatabaseError('Database query failed', 500, null, $e, $sSQL);
 
  65     public function getOne($sSQL)
 
  68             $stmt = $this->connection->query($sSQL);
 
  69             $row = $stmt->fetch(\PDO::FETCH_NUM);
 
  70             if ($row === false) return false;
 
  71         } catch (\PDOException $e) {
 
  72             throw new \Nominatim\DatabaseError('Database query failed', 500, null, $e, $sSQL);
 
  77     public function getAll($sSQL)
 
  80             $stmt = $this->connection->query($sSQL);
 
  81             $rows = $stmt->fetchAll();
 
  82         } catch (\PDOException $e) {
 
  83             throw new \Nominatim\DatabaseError('Database query failed', 500, null, $e, $sSQL);
 
  88     public function getCol($sSQL)
 
  92             $stmt = $this->connection->query($sSQL);
 
  93             while ($val = $stmt->fetchColumn(0)) { // returns first column or false
 
  96         } catch (\PDOException $e) {
 
  97             throw new \Nominatim\DatabaseError('Database query failed', 500, null, $e, $sSQL);
 
 102     public function getAssoc($sSQL)
 
 105             $stmt = $this->connection->query($sSQL);
 
 107             while ($aRow = $stmt->fetch(\PDO::FETCH_NUM)) {
 
 108                 $aList[$aRow[0]] = $aRow[1];
 
 110         } catch (\PDOException $e) {
 
 111             throw new \Nominatim\DatabaseError('Database query failed', 500, null, $e, $sSQL);
 
 117     // St. John's Way => 'St. John\'s Way'
 
 118     public function getDBQuoted($sVal)
 
 120         return $this->connection->quote($sVal);
 
 123     public function getDBQuotedList($aVals)
 
 125         return array_map(function ($sVal) {
 
 126             return $this->getDBQuoted($sVal);
 
 130     public function getArraySQL($a)
 
 132         return 'ARRAY['.join(',', $a).']';
 
 135     public function getLastError()
 
 137         // https://secure.php.net/manual/en/pdo.errorinfo.php
 
 138         return $this->connection->errorInfo();
 
 141     public function tableExists($sTableName)
 
 143         $sSQL = 'SELECT count(*) FROM pg_tables WHERE tablename = '.$this->getDBQuoted($sTableName);
 
 144         return ($this->getOne($sSQL) == 1);
 
 147     public function getPostgresVersion()
 
 149         $sVersionString = $this->getOne('SHOW server_version_num');
 
 150         preg_match('#([0-9]?[0-9])([0-9][0-9])[0-9][0-9]#', $sVersionString, $aMatches);
 
 151         return (float) ($aMatches[1].'.'.$aMatches[2]);
 
 154     public function getPostgisVersion()
 
 156         $sVersionString = $this->getOne('select postgis_lib_version()');
 
 157         preg_match('#^([0-9]+)[.]([0-9]+)[.]#', $sVersionString, $aMatches);
 
 158         return (float) ($aMatches[1].'.'.$aMatches[2]);
 
 161     public static function parseDSN($sDSN)
 
 163         // https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
 
 165         if (preg_match('/^pgsql:(.+)/', $sDSN, $aMatches)) {
 
 166             foreach (explode(';', $aMatches[1]) as $sKeyVal) {
 
 167                 list($sKey, $sVal) = explode('=', $sKeyVal, 2);
 
 168                 if ($sKey == 'host') $sKey = 'hostspec';
 
 169                 if ($sKey == 'dbname') $sKey = 'database';
 
 170                 if ($sKey == 'user') $sKey = 'username';
 
 171                 $aInfo[$sKey] = $sVal;