]> git.openstreetmap.org Git - nominatim.git/blob - utils/setup.php
4f3886f00bb6da28f7ac2311fbca9b17aab1053e
[nominatim.git] / utils / setup.php
1 #!/usr/bin/php -Cq
2 <?php
3
4         require_once(dirname(dirname(__FILE__)).'/lib/init-cmd.php');
5         ini_set('memory_limit', '800M');
6
7         $aCMDOptions = array(
8                 "Create and setup nominatim search system",
9                 array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
10                 array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
11                 array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
12
13                 array('all', '', 0, 1, 1, 1, 'realpath', 'Do the complete process'),
14
15                 array('create-db', '', 0, 1, 0, 0, 'bool', 'Create nominatim db'),
16                 array('setup-db', '', 0, 1, 0, 0, 'bool', 'Build a blank nominatim db'),
17                 array('import-data', '', 0, 1, 1, 1, 'realpath', 'Import a osm file'),
18                 array('create-functions', '', 0, 1, 0, 0, 'bool', 'Create functions'),
19                 array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create main tables'),
20                 array('create-partitions', '', 0, 1, 0, 0, 'bool', 'Create required partition tables and triggers'),
21                 array('load-data', '', 0, 1, 0, 0, 'bool', 'Copy data to live tables from import table'),
22         );
23         getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
24
25         $bDidSomething = false;
26
27         if ($aCMDResult['create-db'] || isset($aCMDResult['all']))
28         {
29                 $bDidSomething = true;
30                 $oDB =& DB::connect(CONST_Database_DSN, false);
31                 if (!PEAR::isError($oDB))
32                 {
33                         fail('database already exists');
34                 }
35                 passthru('createdb nominatim');
36         }
37
38         if ($aCMDResult['create-db'] || isset($aCMDResult['all']))
39         {
40                 $bDidSomething = true;
41                 // TODO: path detection, detection memory, etc.
42
43                 $oDB =& getDB();
44                 passthru('createlang plpgsql nominatim');
45                 pgsqlRunScriptFile(CONST_Path_Postgresql_Contrib.'/_int.sql');
46                 pgsqlRunScriptFile(CONST_Path_Postgresql_Contrib.'/hstore.sql');
47                 pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/postgis.sql');
48                 pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/spatial_ref_sys.sql');
49                 pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql');
50                 pgsqlRunScriptFile(CONST_BasePath.'/data/country_naturaleathdata.sql');
51                 pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql');
52                 pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode.sql');
53                 pgsqlRunScriptFile(CONST_BasePath.'/data/us_statecounty.sql');
54                 pgsqlRunScriptFile(CONST_BasePath.'/data/us_state.sql');
55                 pgsqlRunScriptFile(CONST_BasePath.'/data/worldboundaries.sql');
56         }
57
58         if (isset($aCMDResult['all']) && !isset($aCMDResult['import-data'])) $aCMDResult['import-data'] = $aCMDResult['all'];
59         if (isset($aCMDResult['import-data']) && $aCMDResult['import-data'])
60         {
61                 $bDidSomething = true;
62                 passthru(CONST_BasePath.'/osm2pgsql/osm2pgsql -lsc -O gazetteer -C 10000 --hstore -d nominatim '.$aCMDResult['import-data']);
63         }
64
65         if ($aCMDResult['create-functions'] || isset($aCMDResult['all']))
66         {
67                 $bDidSomething = true;
68                 $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
69                 $sTemplate = str_replace('{modulepath}',CONST_BasePath.'/module', $sTemplate);
70                 pgsqlRunScript($sTemplate);
71         }
72
73         if ($aCMDResult['create-tables'] || isset($aCMDResult['all']))
74         {
75                 $bDidSomething = true;
76                 pgsqlRunScriptFile(CONST_BasePath.'/sql/tables.sql');
77
78                 // re-run the functions
79                 $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
80                 $sTemplate = str_replace('{modulepath}',CONST_BasePath.'/module', $sTemplate);
81                 pgsqlRunScript($sTemplate);
82         }
83
84         if ($aCMDResult['create-partitions'] || isset($aCMDResult['all']))
85         {
86                 $bDidSomething = true;
87                 $oDB =& getDB();
88                 $sSQL = 'select partition from country_name order by country_code';
89                 $aPartitions = $oDB->getCol($sSQL);
90                 if (PEAR::isError($aPartitions))
91                 {
92                         fail($aPartitions->getMessage());
93                 }
94                 $aPartitions[] = 0;
95
96                 $sTemplate = file_get_contents(CONST_BasePath.'/sql/partitions.src.sql');
97                 preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
98                 foreach($aMatches as $aMatch)
99                 {
100                         $sResult = '';
101                         foreach($aPartitions as $sPartitionName)
102                         {
103                                 $sResult .= str_replace('-partition-', $sPartitionName, $aMatch[1]);
104                         }
105                         $sTemplate = str_replace($aMatch[0], $sResult, $sTemplate);
106                 }
107                 pgsqlRunScript($sTemplate);
108         }
109
110         if ($aCMDResult['load-data'] || isset($aCMDResult['all']))
111         {
112                 $bDidSomething = true;
113
114                 $oDB =& getDB();
115                 if (!pg_query($oDB->connection, 'TRUNCATE word')) fail(pg_last_error($oDB->connection));
116                 echo '.';
117                 if (!pg_query($oDB->connection, 'TRUNCATE placex')) fail(pg_last_error($oDB->connection));
118                 echo '.';
119                 if (!pg_query($oDB->connection, 'TRUNCATE place_addressline')) fail(pg_last_error($oDB->connection));
120                 echo '.';
121                 if (!pg_query($oDB->connection, 'TRUNCATE place_boundingbox')) fail(pg_last_error($oDB->connection));
122                 echo '.';
123                 if (!pg_query($oDB->connection, 'TRUNCATE location_area')) fail(pg_last_error($oDB->connection));
124                 echo '.';
125                 if (!pg_query($oDB->connection, 'TRUNCATE search_name')) fail(pg_last_error($oDB->connection));
126                 echo '.';
127                 if (!pg_query($oDB->connection, 'TRUNCATE search_name_blank')) fail(pg_last_error($oDB->connection));
128                 echo '.';
129                 if (!pg_query($oDB->connection, 'DROP SEQUENCE seq_place')) fail(pg_last_error($oDB->connection));
130                 echo '.';
131                 if (!pg_query($oDB->connection, 'CREATE SEQUENCE seq_place start 100000')) fail(pg_last_error($oDB->connection));
132                 echo '.';
133
134                 $iInstances = 16;
135                 $aDBInstances = array();
136                 for($i = 0; $i < $iInstances; $i++)
137                 {
138                         $aDBInstances[$i] =& getDB(true);
139                         $sSQL = 'insert into placex (osm_type, osm_id, class, type, name, admin_level, ';
140                         $sSQL .= 'housenumber, street, isin, postcode, country_code, extratags, ';
141                         $sSQL .= 'geometry) select * from place where osm_id % '.$iInstances.' = '.$i;
142 var_dump($sSQL);
143                         if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
144                 }
145                 $bAnyBusy = true;
146                 while($bAnyBusy)
147                 {
148                         $bAnyBusy = false;
149                         for($i = 0; $i < $iInstances; $i++)
150                         {
151                                 if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
152                         }
153                         sleep(1);
154                         echo '.';
155                 }
156                 echo "\n";
157         }
158
159         if (!$bDidSomething)
160         {
161                 showUsage($aCMDOptions, true);
162         }
163
164         function pgsqlRunScriptFile($sFilename)
165         {
166                 if (!file_exists($sFilename)) fail('unable to find '.$sFilename);
167
168                 // Convert database DSN to psql paramaters
169                 $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
170                 $sCMD = 'psql -f '.$sFilename.' '.$aDSNInfo['database'];
171
172                 $aDescriptors = array(
173                         0 => array('pipe', 'r'),
174                         1 => array('pipe', 'w'),
175                         2 => array('file', '/dev/null', 'a')
176                 );
177                 $ahPipes = null;
178                 $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
179                 if (!is_resource($hProcess)) fail('unable to start pgsql');
180
181                 fclose($ahPipes[0]);
182
183                 // TODO: error checking
184                 while(!feof($ahPipes[1]))
185                 {
186                         echo fread($ahPipes[1], 4096);
187                 }
188                 fclose($ahPipes[1]);
189
190                 proc_close($hProcess);
191         }
192
193         function pgsqlRunScript($sScript)
194         {
195                 // Convert database DSN to psql paramaters
196                 $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
197                 $sCMD = 'psql '.$aDSNInfo['database'];
198
199                 $aDescriptors = array(
200                         0 => array('pipe', 'r'),
201                         1 => array('pipe', 'w'),
202                         2 => array('file', '/dev/null', 'a')
203                 );
204                 $ahPipes = null;
205                 $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
206                 if (!is_resource($hProcess)) fail('unable to start pgsql');
207
208                 fwrite($ahPipes[0], $sScript);
209                 fclose($ahPipes[0]);
210
211                 // TODO: error checking
212                 while(!feof($ahPipes[1]))
213                 {
214                         echo fread($ahPipes[1], 4096);
215                 }
216                 fclose($ahPipes[1]);
217
218                 proc_close($hProcess);
219         }