From 15a1666f8a1e19c338015fccd502be6cfd5c24df Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Tue, 15 Dec 2020 15:12:28 +0100 Subject: [PATCH] replace database settings with dotenv variant As we can't refer to the project root dir in the module path, the module path may now also be a relative directory which is then taken as being relative to the project root path. Moves the checkModulePresence() function into the Setup class, so that it can work on the computed absolute module path. --- lib/DB.php | 4 +- lib/cmd.php | 2 +- lib/lib.php | 5 ++ lib/setup/SetupClass.php | 48 ++++++++---- lib/setup_functions.php | 15 ---- settings/defaults.php | 4 - settings/env.defaults | 125 ++++++++++++++++++++++++++++++++ utils/check_import_finished.php | 2 +- utils/specialphrases.php | 2 +- utils/update.php | 2 +- 10 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 settings/env.defaults diff --git a/lib/DB.php b/lib/DB.php index 2b53dba8..0454a0ff 100644 --- a/lib/DB.php +++ b/lib/DB.php @@ -12,9 +12,9 @@ class DB { protected $connection; - public function __construct($sDSN = CONST_Database_DSN) + public function __construct($sDSN = null) { - $this->sDSN = $sDSN; + $this->sDSN = $sDSN ?? getSetting('DATABASE_DSN'); } public function connect($bNew = false, $bPersistent = true) diff --git a/lib/cmd.php b/lib/cmd.php index b72c1bb4..7337f814 100644 --- a/lib/cmd.php +++ b/lib/cmd.php @@ -147,7 +147,7 @@ function repeatWarnings() function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreErrors = false) { // Convert database DSN to psql parameters - $aDSNInfo = \Nominatim\DB::parseDSN(CONST_Database_DSN); + $aDSNInfo = \Nominatim\DB::parseDSN(getSetting('DATABASE_DSN')); if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432; $oCmd = new \Nominatim\Shell('psql'); diff --git a/lib/lib.php b/lib/lib.php index 9861cdd0..753159d2 100644 --- a/lib/lib.php +++ b/lib/lib.php @@ -18,6 +18,11 @@ function loadSettings($sProjectDir) $dotenv->load(CONST_DataDir.'/settings/env.defaults'); } +function getSetting($sConfName) +{ + return $_ENV['NOMINATIM_'.$sConfName]; +} + function fail($sError, $sUserError = false) { if (!$sUserError) $sUserError = $sError; diff --git a/lib/setup/SetupClass.php b/lib/setup/SetupClass.php index 6114689f..489ab2ec 100755 --- a/lib/setup/SetupClass.php +++ b/lib/setup/SetupClass.php @@ -42,11 +42,14 @@ class SetupFunctions $this->iCacheMemory = getCacheMemoryMB(); } - $this->sModulePath = CONST_Database_Module_Path; + $this->sModulePath = getSetting('DATABASE_MODULE_PATH'); + if (strlen($this->sModulePath) == 0 || $this->sModulePath[0] != '/') { + $this->sModulePath = CONST_InstallDir.'/'.$this->sModulePath; + } info('module path: ' . $this->sModulePath); // parse database string - $this->aDSNInfo = \Nominatim\DB::parseDSN(CONST_Database_DSN); + $this->aDSNInfo = \Nominatim\DB::parseDSN(getSetting('DATABASE_DSN')); if (!isset($this->aDSNInfo['port'])) { $this->aDSNInfo['port'] = 5432; } @@ -86,7 +89,7 @@ class SetupFunctions $oDB = new \Nominatim\DB; if ($oDB->checkConnection()) { - fail('database already exists ('.CONST_Database_DSN.')'); + fail('database already exists ('.getSetting('DATABASE_DSN').')'); } $oCmd = (new \Nominatim\Shell('createdb')) @@ -130,15 +133,16 @@ class SetupFunctions exit(1); } - $i = $this->db()->getOne("select count(*) from pg_user where usename = '".CONST_Database_Web_User."'"); + $sPgUser = getSetting('DATABASE_WEBUSER'); + $i = $this->db()->getOne("select count(*) from pg_user where usename = '$sPgUser'"); if ($i == 0) { - echo "\nERROR: Web user '".CONST_Database_Web_User."' does not exist. Create it with:\n"; - echo "\n createuser ".CONST_Database_Web_User."\n\n"; + echo "\nERROR: Web user '".$sPgUser."' does not exist. Create it with:\n"; + echo "\n createuser ".$sPgUser."\n\n"; exit(1); } // Try accessing the C module, so we know early if something is wrong - checkModulePresence(); // raises exception on failure + $this->checkModulePresence(); // raises exception on failure if (!file_exists(CONST_DataDir.'/data/country_osm_grid.sql.gz')) { echo 'Error: you need to download the country_osm_grid first:'; @@ -234,7 +238,7 @@ class SetupFunctions info('Create Functions'); // Try accessing the C module, so we know early if something is wrong - checkModulePresence(); // raises exception on failure + $this->checkModulePresence(); // raises exception on failure $this->createSqlFunctions(); } @@ -352,7 +356,7 @@ class SetupFunctions $iLoadThreads = max(1, $this->iInstances - 1); for ($i = 0; $i < $iLoadThreads; $i++) { // https://secure.php.net/manual/en/function.pg-connect.php - $DSN = CONST_Database_DSN; + $DSN = getSetting('DATABASE_DSN'); $DSN = preg_replace('/^pgsql:/', '', $DSN); $DSN = preg_replace('/;/', ' ', $DSN); $aDBInstances[$i] = pg_connect($DSN, PGSQL_CONNECT_FORCE_NEW); @@ -372,7 +376,7 @@ class SetupFunctions // last thread for interpolation lines // https://secure.php.net/manual/en/function.pg-connect.php - $DSN = CONST_Database_DSN; + $DSN = getSetting('DATABASE_DSN'); $DSN = preg_replace('/^pgsql:/', '', $DSN); $DSN = preg_replace('/;/', ' ', $DSN); $aDBInstances[$iLoadThreads] = pg_connect($DSN, PGSQL_CONNECT_FORCE_NEW); @@ -442,7 +446,7 @@ class SetupFunctions $aDBInstances = array(); for ($i = 0; $i < $this->iInstances; $i++) { // https://secure.php.net/manual/en/function.pg-connect.php - $DSN = CONST_Database_DSN; + $DSN = getSetting('DATABASE_DSN'); $DSN = preg_replace('/^pgsql:/', '', $DSN); $DSN = preg_replace('/;/', ' ', $DSN); $aDBInstances[$i] = pg_connect($DSN, PGSQL_CONNECT_FORCE_NEW | PGSQL_CONNECT_ASYNC); @@ -542,7 +546,7 @@ class SetupFunctions public function index($bIndexNoanalyse) { - checkModulePresence(); // raises exception on failure + $this->checkModulePresence(); // raises exception on failure $oBaseCmd = (new \Nominatim\Shell(CONST_DataDir.'/nominatim/nominatim.py')) ->addParams('--database', $this->aDSNInfo['database']) @@ -714,7 +718,7 @@ class SetupFunctions fwrite($rOutputFile, " CONST_Tablespace_Address_Data, @@ -938,4 +942,20 @@ if (file_exists(getenv('NOMINATIM_SETTINGS'))) require_once(getenv('NOMINATIM_SE { return !($this->db()->tableExists('search_name')); } + + /** + * Try accessing the C module, so we know early if something is wrong. + * + * Raises Nominatim\DatabaseError on failure + */ + private function checkModulePresence() + { + $sSQL = "CREATE FUNCTION nominatim_test_import_func(text) RETURNS text AS '"; + $sSQL .= $this->sModulePath . "/nominatim.so', 'transliteration' LANGUAGE c IMMUTABLE STRICT"; + $sSQL .= ';DROP FUNCTION nominatim_test_import_func(text);'; + + $oDB = new \Nominatim\DB(); + $oDB->connect(); + $oDB->exec($sSQL, null, 'Database server failed to load '.$this->sModulePath.'/nominatim.so module'); + } } diff --git a/lib/setup_functions.php b/lib/setup_functions.php index 43f30a09..5aa5919b 100755 --- a/lib/setup_functions.php +++ b/lib/setup_functions.php @@ -14,18 +14,3 @@ function checkInFile($sOSMFile) fail('osm-file "' . $aCMDResult['osm-file'] . '" not readable'); } } - -function checkModulePresence() -{ - // Try accessing the C module, so we know early if something is wrong. - // Raises Nominatim\DatabaseError on failure - - $sModulePath = CONST_Database_Module_Path; - $sSQL = "CREATE FUNCTION nominatim_test_import_func(text) RETURNS text AS '"; - $sSQL .= $sModulePath . "/nominatim.so', 'transliteration' LANGUAGE c IMMUTABLE STRICT"; - $sSQL .= ';DROP FUNCTION nominatim_test_import_func(text);'; - - $oDB = new \Nominatim\DB(); - $oDB->connect(); - $oDB->exec($sSQL, null, 'Database server failed to load '.$sModulePath.'/nominatim.so module'); -} diff --git a/settings/defaults.php b/settings/defaults.php index 49c2d217..1f146a4b 100644 --- a/settings/defaults.php +++ b/settings/defaults.php @@ -2,10 +2,6 @@ if (file_exists(getenv('NOMINATIM_SETTINGS'))) require_once(getenv('NOMINATIM_SETTINGS')); if (file_exists(CONST_InstallDir.'/settings/local.php')) require_once(CONST_InstallDir.'/settings/local.php'); -// General settings -@define('CONST_Database_DSN', 'pgsql:dbname=nominatim'); // or add ;host=...;port=...;user=...;password=... -@define('CONST_Database_Web_User', 'www-data'); -@define('CONST_Database_Module_Path', CONST_InstallDir.'/module'); @define('CONST_Max_Word_Frequency', '50000'); @define('CONST_Limit_Reindexing', true); // Restrict search languages. diff --git a/settings/env.defaults b/settings/env.defaults new file mode 100644 index 00000000..45b0fc6b --- /dev/null +++ b/settings/env.defaults @@ -0,0 +1,125 @@ +# .env +# Default configuration settings for Nominatim + +# Database connection string. +# Add host, port, user etc through additional semicolon-separated attributes. +# e.g. ;host=...;port=...;user=...;password=... +NOMINATIM_DATABASE_DSN="pgsql:dbname=nominatim" + +# Database web user. +# Nominatim sets up read-only access for this user during installation. +NOMINATIM_DATABASE_WEBUSER="www-data" + +# Directory where to find the PostgreSQL server module. +# When a relative path is given, it will be searched relative to the project +# directory. +NOMINATIM_DATABASE_MODULE_PATH="module" + +#@define('CONST_Max_Word_Frequency', '50000'); +#@define('CONST_Limit_Reindexing', true); +#// Restrict search languages. +#// Normally Nominatim will include all language variants of name:XX +#// in the search index. Set this to a comma separated list of language +#// codes, to restrict import to a subset of languages. +#// Currently only affects the import of country names and special phrases. +#@define('CONST_Languages', false); +#// Rules for normalizing terms for comparison before doing comparisons. +#// The default is to remove accents and punctuation and to lower-case the +#// term. Spaces are kept but collapsed to one standard space. +#@define('CONST_Term_Normalization_Rules', ":: NFD (); [[:Nonspacing Mark:] [:Cf:]] >; :: lower (); [[:Punctuation:][:Space:]]+ > ' '; :: NFC ();"); +# +#/* Set to true after importing Tiger house number data for the US. +# Note: The tables must already exist or queries will throw errors. +# After changing this setting run ./utils/setup --create-functions +# again. */ +#@define('CONST_Use_US_Tiger_Data', false); +#/* Set to true after importing other external house number data. +# Note: the aux tables must already exist or queries will throw errors. +# After changing this setting run ./utils/setup --create-functions +# again. */ +#@define('CONST_Use_Aux_Location_data', false); +# +#// Proxy settings +#@define('CONST_HTTP_Proxy', false); +#@define('CONST_HTTP_Proxy_Host', 'proxy.mydomain.com'); +#@define('CONST_HTTP_Proxy_Port', '3128'); +#@define('CONST_HTTP_Proxy_Login', ''); +#@define('CONST_HTTP_Proxy_Password', ''); +# +#// Paths +#@define('CONST_ExtraDataPath', CONST_BasePath.'/data'); +#@define('CONST_Osm2pgsql_Binary', CONST_InstallPath.'/osm2pgsql/osm2pgsql'); +#@define('CONST_Pyosmium_Binary', '@PYOSMIUM_PATH@'); +#@define('CONST_Tiger_Data_Path', CONST_ExtraDataPath.'/tiger'); +#@define('CONST_Wikipedia_Data_Path', CONST_ExtraDataPath); +#@define('CONST_Phrase_Config', CONST_BasePath.'/settings/phrase_settings.php'); +#@define('CONST_Address_Level_Config', CONST_BasePath.'/settings/address-levels.json'); +#@define('CONST_Import_Style', CONST_BasePath.'/settings/import-full.style'); +# +#// osm2pgsql settings +#@define('CONST_Osm2pgsql_Flatnode_File', null); +# +#// tablespace settings +#// osm2pgsql caching tables (aka slim mode tables) - update only +#@define('CONST_Tablespace_Osm2pgsql_Data', false); +#@define('CONST_Tablespace_Osm2pgsql_Index', false); +#// osm2pgsql output tables (aka main table) - update only +#@define('CONST_Tablespace_Place_Data', false); +#@define('CONST_Tablespace_Place_Index', false); +#// address computation tables - update only +#@define('CONST_Tablespace_Address_Data', false); +#@define('CONST_Tablespace_Address_Index', false); +#// search tables - needed for lookups +#@define('CONST_Tablespace_Search_Data', false); +#@define('CONST_Tablespace_Search_Index', false); +#// additional data, e.g. TIGER data, type searches - needed for lookups +#@define('CONST_Tablespace_Aux_Data', false); +#@define('CONST_Tablespace_Aux_Index', false); +# +#//// Replication settings +# +#// Base URL of replication service +#@define('CONST_Replication_Url', 'https://planet.openstreetmap.org/replication/minute'); +# +#// Maximum size in MB of data to download per batch +#@define('CONST_Replication_Max_Diff_size', '30'); +#// How long until the service publishes the next diff +#// (relative to the age of data in the diff). +#@define('CONST_Replication_Update_Interval', '75'); +#// How long to sleep when no update could be found +#@define('CONST_Replication_Recheck_Interval', '60'); +# +#// If true, send CORS headers to allow access +#@define('CONST_NoAccessControl', true); +# +#// Set this to the /mapicon directory of your nominatim-ui to enable returning +#// icon URLs with the results. +#@define('CONST_MapIcon_URL', false); +#// Language to assume when none is supplied with the query. +#// When set to false, the local language (i.e. the name tag without suffix) +#// will be used. +#@define('CONST_Default_Language', false); +# +#@define('CONST_Search_AreaPolygons', true); +# +#@define('CONST_Search_BatchMode', false); +# +#@define('CONST_Search_NameOnlySearchFrequencyThreshold', 500); +#// If set to true, then reverse order of queries will be tried by default. +#// When set to false only selected languages allow reverse search. +#@define('CONST_Search_ReversePlanForAll', true); +# +#// Maximum number of OSM ids that may be queried at once +#// for the places endpoint. +#@define('CONST_Places_Max_ID_count', 50); +# +#// Number of different geometry formats that may be queried in parallel. +#// Set to zero to disable polygon output. +#@define('CONST_PolygonOutput_MaximumTypes', 1); +# +#// Log settings +#// Set to true to log into new_query_log table. +#// You should set up a cron job that regularly clears out this table. +#@define('CONST_Log_DB', false); +#// Set to a file name to enable logging to a file. +#@define('CONST_Log_File', false); diff --git a/utils/check_import_finished.php b/utils/check_import_finished.php index 1eb012d4..570378dd 100755 --- a/utils/check_import_finished.php +++ b/utils/check_import_finished.php @@ -35,7 +35,7 @@ if ($oDB->checkConnection()) { echo <<< END Hints: * Is the database server started? - * Check the CONST_Database_DSN variable in build/settings/local.php + * Check the NOMINATIM_DATABASE_DSN variable in your local .env * Try connecting to the database with the same settings END; diff --git a/utils/specialphrases.php b/utils/specialphrases.php index d2bc7041..9e6da265 100644 --- a/utils/specialphrases.php +++ b/utils/specialphrases.php @@ -147,7 +147,7 @@ if ($aCMDResult['wiki-import']) { . ";\n", pg_escape_string($aPair[0]), pg_escape_string($aPair[1]), - CONST_Database_Web_User + getSetting('DATABASE_WEBUSER'); ); } diff --git a/utils/update.php b/utils/update.php index ff8b0c00..9b68ecdb 100644 --- a/utils/update.php +++ b/utils/update.php @@ -57,7 +57,7 @@ $oDB = new Nominatim\DB(); $oDB->connect(); $fPostgresVersion = $oDB->getPostgresVersion(); -$aDSNInfo = Nominatim\DB::parseDSN(CONST_Database_DSN); +$aDSNInfo = Nominatim\DB::parseDSN(getSetting('DATABASE_DSN')); if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432; // cache memory to be used by osm2pgsql, should not be more than the available memory -- 2.45.1