X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/409ded385f10cbe3d32ff20411f48b240bf6f328..e10d11c6c7a5a96f645b9155a55e56f874ed6042:/lib/setup/SetupClass.php diff --git a/lib/setup/SetupClass.php b/lib/setup/SetupClass.php index 74dabb24..0f96bc8b 100755 --- a/lib/setup/SetupClass.php +++ b/lib/setup/SetupClass.php @@ -2,6 +2,8 @@ namespace Nominatim\Setup; +require_once(CONST_BasePath.'/lib/setup/AddressLevelParser.php'); + class SetupFunctions { protected $iCacheMemory; @@ -90,7 +92,7 @@ class SetupFunctions if ($result != 0) fail('Error executing external command: '.$sCreateDBCmd); } - public function connect($sDatabaseDSN) + public function connect() { $this->oDB =& getDB(); } @@ -102,7 +104,7 @@ class SetupFunctions $fPostgresVersion = getPostgresVersion($this->oDB); echo 'Postgres version found: '.$fPostgresVersion."\n"; - if ($fPostgresVersion < 9.1) { + if ($fPostgresVersion < 9.01) { fail('Minimum supported version of Postgresql is 9.1.'); } @@ -230,7 +232,7 @@ class SetupFunctions $this->createSqlFunctions(); } - public function createTables() + public function createTables($bReverseOnly = false) { info('Create Tables'); @@ -268,6 +270,13 @@ class SetupFunctions ); $this->pgsqlRunScript($sTemplate, false); + + if ($bReverseOnly) { + $this->pgExec('DROP TABLE search_name'); + } + + $oAlParser = new AddressLevelParser(CONST_Address_Level_Config); + $oAlParser->createTable($this->oDB, 'address_levels'); } public function createPartitionTables() @@ -344,41 +353,41 @@ class SetupFunctions { info('Drop old Data'); - if (!pg_query($this->oDB->connection, 'TRUNCATE word')) fail(pg_last_error($this->oDB->connection)); - echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE placex')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE word'); echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE location_property_osmline')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE placex'); echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE place_addressline')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE location_property_osmline'); echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE place_boundingbox')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE place_addressline'); echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE location_area')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE place_boundingbox'); echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE search_name')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE location_area'); echo '.'; - if (!pg_query($this->oDB->connection, 'TRUNCATE search_name_blank')) fail(pg_last_error($this->oDB->connection)); + if (!$this->dbReverseOnly()) { + $this->pgExec('TRUNCATE search_name'); + echo '.'; + } + $this->pgExec('TRUNCATE search_name_blank'); echo '.'; - if (!pg_query($this->oDB->connection, 'DROP SEQUENCE seq_place')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('DROP SEQUENCE seq_place'); echo '.'; - if (!pg_query($this->oDB->connection, 'CREATE SEQUENCE seq_place start 100000')) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('CREATE SEQUENCE seq_place start 100000'); echo '.'; $sSQL = 'select distinct partition from country_name'; $aPartitions = chksql($this->oDB->getCol($sSQL)); if (!$this->bNoPartitions) $aPartitions[] = 0; foreach ($aPartitions as $sPartition) { - if (!pg_query($this->oDB->connection, 'TRUNCATE location_road_'.$sPartition)) fail(pg_last_error($this->oDB->connection)); + $this->pgExec('TRUNCATE location_road_'.$sPartition); echo '.'; } // used by getorcreate_word_id to ignore frequent partial words $sSQL = 'CREATE OR REPLACE FUNCTION get_maxwordfreq() RETURNS integer AS '; $sSQL .= '$$ SELECT '.CONST_Max_Word_Frequency.' as maxwordfreq; $$ LANGUAGE SQL IMMUTABLE'; - if (!pg_query($this->oDB->connection, $sSQL)) { - fail(pg_last_error($this->oDB->connection)); - } + $this->pgExec($sSQL); echo ".\n"; // pre-create the word list @@ -523,10 +532,7 @@ class SetupFunctions public function calculatePostcodes($bCMDResultAll) { info('Calculate Postcodes'); - if (!pg_query($this->oDB->connection, 'TRUNCATE location_postcode')) { - fail(pg_last_error($this->oDB->connection)); - } - + $this->pgExec('TRUNCATE location_postcode'); $sSQL = 'INSERT INTO location_postcode'; $sSQL .= ' (place_id, indexed_status, country_code, postcode, geometry) '; @@ -537,10 +543,7 @@ class SetupFunctions $sSQL .= " WHERE address ? 'postcode' AND address->'postcode' NOT SIMILAR TO '%(,|;)%'"; $sSQL .= ' AND geometry IS NOT null'; $sSQL .= ' GROUP BY country_code, pc'; - - if (!pg_query($this->oDB->connection, $sSQL)) { - fail(pg_last_error($this->oDB->connection)); - } + $this->pgExec($sSQL); if (CONST_Use_Extra_US_Postcodes) { // only add postcodes that are not yet available in OSM @@ -551,7 +554,7 @@ class SetupFunctions $sSQL .= ' FROM us_postcode WHERE postcode NOT IN'; $sSQL .= ' (SELECT postcode FROM location_postcode'; $sSQL .= " WHERE country_code = 'us')"; - if (!pg_query($this->oDB->connection, $sSQL)) fail(pg_last_error($this->oDB->connection)); + $this->pgExec($sSQL); } // add missing postcodes for GB (if available) @@ -561,21 +564,17 @@ class SetupFunctions $sSQL .= ' FROM gb_postcode WHERE postcode NOT IN'; $sSQL .= ' (SELECT postcode FROM location_postcode'; $sSQL .= " WHERE country_code = 'gb')"; - if (!pg_query($this->oDB->connection, $sSQL)) fail(pg_last_error($this->oDB->connection)); + $this->pgExec($sSQL); if (!$bCMDResultAll) { $sSQL = "DELETE FROM word WHERE class='place' and type='postcode'"; $sSQL .= 'and word NOT IN (SELECT postcode FROM location_postcode)'; - if (!pg_query($this->oDB->connection, $sSQL)) { - fail(pg_last_error($this->oDB->connection)); - } + $this->pgExec($sSQL); } + $sSQL = 'SELECT count(getorcreate_postcode_id(v)) FROM '; $sSQL .= '(SELECT distinct(postcode) as v FROM location_postcode) p'; - - if (!pg_query($this->oDB->connection, $sSQL)) { - fail(pg_last_error($this->oDB->connection)); - } + $this->pgExec($sSQL); } public function index($bIndexNoanalyse) @@ -596,20 +595,23 @@ class SetupFunctions fail('error status ' . $iStatus . ' running nominatim!'); } if (!$bIndexNoanalyse) $this->pgsqlRunScript('ANALYSE'); + info('Index ranks 5 - 25'); $iStatus = $this->runWithPgEnv($sBaseCmd.' -r 5 -R 25'); if ($iStatus != 0) { fail('error status ' . $iStatus . ' running nominatim!'); } if (!$bIndexNoanalyse) $this->pgsqlRunScript('ANALYSE'); + info('Index ranks 26 - 30'); $iStatus = $this->runWithPgEnv($sBaseCmd.' -r 26'); if ($iStatus != 0) { fail('error status ' . $iStatus . ' running nominatim!'); } + info('Index postcodes'); $sSQL = 'UPDATE location_postcode SET indexed_status = 0'; - if (!pg_query($this->oDB->connection, $sSQL)) fail(pg_last_error($this->oDB->connection)); + $this->pgExec($sSQL); } public function createSearchIndices() @@ -617,6 +619,9 @@ class SetupFunctions info('Create Search indices'); $sTemplate = file_get_contents(CONST_BasePath.'/sql/indices.src.sql'); + if (!$this->dbReverseOnly()) { + $sTemplate .= file_get_contents(CONST_BasePath.'/sql/indices_search.src.sql'); + } $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate); $sTemplate = $this->replaceTablespace( '{ts:address-index}', @@ -703,15 +708,17 @@ class SetupFunctions if (!$bFound) array_push($aDropTables, $sTable); } foreach ($aDropTables as $sDrop) { - if ($this->sVerbose) echo "dropping table $sDrop\n"; + if ($this->sVerbose) echo "Dropping table $sDrop\n"; @pg_query($this->oDB->connection, "DROP TABLE $sDrop CASCADE"); // ignore warnings/errors as they might be caused by a table having // been deleted already by CASCADE } if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) { - if ($sVerbose) echo 'deleting '.CONST_Osm2pgsql_Flatnode_File."\n"; - unlink(CONST_Osm2pgsql_Flatnode_File); + if (file_exists(CONST_Osm2pgsql_Flatnode_File)) { + if ($this->sVerbose) echo 'Deleting '.CONST_Osm2pgsql_Flatnode_File."\n"; + unlink(CONST_Osm2pgsql_Flatnode_File); + } } } @@ -757,6 +764,10 @@ class SetupFunctions if (!CONST_Use_Aux_Location_data) { $sTemplate = str_replace('-- %NOAUXDATA% ', '', $sTemplate); } + + $sReverseOnly = $this->dbReverseOnly() ? 'true' : 'false'; + $sTemplate = str_replace('%REVERSE-ONLY%', $sReverseOnly, $sTemplate); + $this->pgsqlRunScript($sTemplate); } @@ -854,4 +865,31 @@ class SetupFunctions return runWithEnv($sCmd, $aProcEnv); } + + /** + * Execute the SQL command on the open database. + * + * @param string $sSQL SQL command to execute. + * + * @return null + * + * @pre connect() must have been called. + */ + private function pgExec($sSQL) + { + if (!pg_query($this->oDB->connection, $sSQL)) { + fail(pg_last_error($this->oDB->connection)); + } + } + + /** + * Check if the database is in reverse-only mode. + * + * @return True if there is no search_name table and infrastructure. + */ + private function dbReverseOnly() + { + $sSQL = "SELECT count(*) FROM pg_tables WHERE tablename = 'search_name'"; + return !(chksql($this->oDB->getOne($sSQL))); + } }