]> git.openstreetmap.org Git - nominatim.git/blob - lib/setup/AddressLevelParser.php
Merge pull request #1526 from lonvia/index-concurrently
[nominatim.git] / lib / setup / AddressLevelParser.php
1 <?php
2
3 namespace Nominatim\Setup;
4
5 /**
6  * Parses an address level description.
7  */
8 class AddressLevelParser
9 {
10     private $aLevels;
11
12     public function __construct($sDescriptionFile)
13     {
14         $sJson = file_get_contents($sDescriptionFile);
15         $this->aLevels = json_decode($sJson, true);
16         if (!$this->aLevels) {
17             switch (json_last_error()) {
18                 case JSON_ERROR_NONE:
19                     break;
20                 case JSON_ERROR_DEPTH:
21                     fail('JSON error - Maximum stack depth exceeded');
22                     break;
23                 case JSON_ERROR_STATE_MISMATCH:
24                     fail('JSON error - Underflow or the modes mismatch');
25                     break;
26                 case JSON_ERROR_CTRL_CHAR:
27                     fail('JSON error - Unexpected control character found');
28                     break;
29                 case JSON_ERROR_SYNTAX:
30                     fail('JSON error - Syntax error, malformed JSON');
31                     break;
32                 case JSON_ERROR_UTF8:
33                     fail('JSON error - Malformed UTF-8 characters, possibly incorrectly encoded');
34                     break;
35                 default:
36                     fail('JSON error - Unknown error');
37                     break;
38             }
39         }
40     }
41
42     /**
43      * Dump the description into a database table.
44      *
45      * @param object $oDB    Database conneciton to use.
46      * @param string $sTable Name of table to create.
47      *
48      * @return null
49      *
50      * A new table is created. Any previously existing table is dropped.
51      * The table has the following columns:
52      * country, class, type, rank_search, rank_address.
53      */
54     public function createTable($oDB, $sTable)
55     {
56         $oDB->exec('DROP TABLE IF EXISTS '.$sTable);
57         $sSql = 'CREATE TABLE '.$sTable;
58         $sSql .= '(country_code varchar(2), class TEXT, type TEXT,';
59         $sSql .= ' rank_search SMALLINT, rank_address SMALLINT)';
60         $oDB->exec($sSql);
61
62         $sSql = 'CREATE UNIQUE INDEX ON '.$sTable.' (country_code, class, type)';
63         $oDB->exec($sSql);
64
65         $sSql = 'INSERT INTO '.$sTable.' VALUES ';
66         foreach ($this->aLevels as $aLevel) {
67             $aCountries = array();
68             if (isset($aLevel['countries'])) {
69                 foreach ($aLevel['countries'] as $sCountry) {
70                     $aCountries[$sCountry] = $oDB->getDBQuoted($sCountry);
71                 }
72             } else {
73                 $aCountries['NULL'] = 'NULL';
74             }
75             foreach ($aLevel['tags'] as $sKey => $aValues) {
76                 foreach ($aValues as $sValue => $mRanks) {
77                     $aFields = array(
78                         $oDB->getDBQuoted($sKey),
79                         $sValue ? $oDB->getDBQuoted($sValue) : 'NULL'
80                     );
81                     if (is_array($mRanks)) {
82                         $aFields[] = (string) $mRanks[0];
83                         $aFields[] = (string) $mRanks[1];
84                     } else {
85                         $aFields[] = (string) $mRanks;
86                         $aFields[] = (string) $mRanks;
87                     }
88                     $sLine = ','.join(',', $aFields).'),';
89
90                     foreach ($aCountries as $sCountries) {
91                         $sSql .= '('.$sCountries.$sLine;
92                     }
93                 }
94             }
95         }
96         $oDB->exec(rtrim($sSql, ','));
97     }
98 }