Skip to content

Commit

Permalink
Correct issue with invalid "hash" value
Browse files Browse the repository at this point in the history
[WARNING] This commit needs an update of existing database and change the GeoJSON output (see keywords change).

The "hash" and "parentHash" keys from the keywords property are strings generated by a md5 cut at 15 characters. The "hash" is used as the key for the associative keywords property.

In rare case the "hash" is a string of numbers only (e.g. for state:zavaska, the "hash" is "419424100927284"). As the key of associative array, PHP interprets this as an integer even if it's casted as string.

To avoid this issue, we changed the keywords structure as follow :

Previous structure :

"keywords": {
                    "bce097de57d1ab7": {
                        "name": "Europe",
                        "normalized": "europe",
                        "type": "continent",
                        "href": "http:\/\/resto.mapshup.com\/2.1\/api\/collections\/search.json?&lang=en&q=Europe"
                    },
                    "936bcbcf5c43fbd": {
                        "name": "France",
                        "normalized": "france",
                        "type": "country",
                        "parentHash": "bce097de57d1ab7",
                        "value": 83.78,
                        "gcover": 5.79,
                        "href": "http:\/\/resto.mapshup.com\/2.1\/api\/collections\/search.json?&lang=en&q=France"
                    }
}

New structure :

"keywords": [
                    {
                        "id":"bce097de57d1ab7",
                        "name": "Europe",
                        "normalized": "europe",
                        "type": "continent",
                        "href": "http:\/\/resto.mapshup.com\/2.1\/api\/collections\/search.json?&lang=en&q=Europe"
                    },
                    {
                       "id":"936bcbcf5c43fbd",
                        "name": "France",
                        "normalized": "france",
                        "type": "country",
                        "parentHash": "bce097de57d1ab7",
                        "value": 83.78,
                        "gcover": 5.79,
                        "href": "http:\/\/resto.mapshup.com\/2.1\/api\/collections\/search.json?&lang=en&q=France"
                    }
]
  • Loading branch information
jjrom committed Apr 4, 2016
1 parent 28d5e9d commit eb64040
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 102 deletions.
8 changes: 4 additions & 4 deletions _examples/resources/resource_Example.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@
"wktBounds": "POLYGON((-151.94440577844645 -16.250438048434496,-151.27338568830842 -16.288706470573882,-151.27705117976558 -16.845826458873454,-151.94002056020608 -16.811713604959639))",
"wktCenter": "POINT (-151.60234844839167 -16.549982658384916)",
"wktFootprint": "POLYGON((-151.94440577844645 -16.250438048434496,-151.27338568830842 -16.288706470573882,-151.27705117976558 -16.845826458873454,-151.94002056020608 -16.811713604959639,-151.94440577844645 -16.250438048434496))",
"keywords": {
"other:test1" : {
"keywords": [
{
"name":"Test 1",
"type":"other",
"value": 94
},
"other:test1" : {
{
"name":"Test 2",
"type": "other",
"value": null
}
}
]
}
}
97 changes: 97 additions & 0 deletions _install/migration/updateKeywords.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env php
<?php

/**
* Return PostgreSQL database handler
*
* @param array $options
* @throws Exception
*/
function getHandler($options = array()) {

$dbh = null;

if (isset($options) && isset($options['dbname'])) {
try {
$dbInfo = array(
'dbname=' . $options['dbname'],
'user=' . $options['user'],
'password=' . $options['password']
);
/*
* If host is specified, then TCP/IP connection is used
* Otherwise socket connection is used
*/
if (isset($options['host'])) {
$dbInfo[] = 'host=' . $options['host'];
$dbInfo[] = 'port=' . (isset($options['port']) ? $options['port'] : '5432');
}
$dbh = pg_connect(join(' ', $dbInfo));
if (!$dbh) {
throw new Exception();
}
} catch (Exception $e) {
echo 'Database connection error';
exit;
}
}

return $dbh;
}

/**
* Upgrade resto v2.1 json keywords to resto v2.2 json keywords
* @param array $oldJSON
*/
function upgradeJSON($oldJSON) {
$newJSON = array();
foreach ($oldJSON as $key => $value) {
$newValue = array();
// Force identifier to be a string
$newValue['id'] = "" . $key;
foreach ($value as $key2 => $value2) {
$newValue[$key2] = $value2;
}
array_push($newJSON, $newValue);
}
return $newJSON;
}


$help = "\nGenerate SQL commands to update keywords column to follow resto v2.2 interface\n";
$help .= "\n USAGE : updateKeywords -u <db user> -p <db password> \n";
$help .= " OPTIONS:\n";
$help .= " -u <db user> : Database user name with update rights on resto database\n";
$help .= " -p <db password> : Database user password\n";
$options = getopt("u:p:h");
foreach ($options as $option => $value) {
if ($option === "u") {
$username = $value;
}
if ($option === "p") {
$password = $value;
}
if ($option === "h") {
echo $help;
exit;
}
}

if (!isset($username) || !isset($password)) {
echo $help;
exit;
}

$dbh = getHandler(array(
'dbname' => 'resto',
'host' => 'localhost',
'port' => 5432,
'user' => $username,
'password' => $password
));

$results = pg_query($dbh, 'SELECT identifier, keywords FROM resto.features ORDER BY identifier');
while ($result = pg_fetch_assoc($results)) {
$newJSON = upgradeJSON(json_decode($result['keywords'], true));
echo 'UPDATE resto.features SET keywords=\'' . pg_escape_string(json_encode($newJSON)) . '\' WHERE identifier=\'' . $result['identifier'] . '\';' ."\n";
}
10 changes: 5 additions & 5 deletions include/resto/Drivers/PostgreSQL/Functions_features.php
Original file line number Diff line number Diff line change
Expand Up @@ -462,18 +462,18 @@ private function propertiesToColumns($collection, $properties) {
*/
private function getHashes($keywords) {
$hashes = array();
foreach (array_keys($keywords) as $hash) {
for ($i = count($keywords); $i--;) {

/*
* Do not index keywords if relative cover is lower than 10 % or if absolute coverage is lower than 20%
*/
if (isset($keywords[$hash]['value']) && $keywords[$hash]['value'] < 10) {
if (!isset($keywords[$hash]['gcover']) || $keywords[$hash]['gcover'] < 20) {
if (isset($keywords[$i]['value']) && $keywords[$i]['value'] < 10) {
if (!isset($keywords[$i]['gcover']) || $keywords[$i]['gcover'] < 20) {
continue;
}
}
$hashes[] = '"' . pg_escape_string($hash) . '"';
$hashes[] = '"' . pg_escape_string($keywords[$hash]['type'] . ':' . (isset($keywords[$hash]['normalized']) ? $keywords[$hash]['normalized'] : strtolower($keywords[$hash]['name']))) . '"';
$hashes[] = '"' . pg_escape_string($keywords[$i]['id']) . '"';
$hashes[] = '"' . pg_escape_string($keywords[$i]['type'] . ':' . (isset($keywords[$i]['normalized']) ? $keywords[$i]['normalized'] : strtolower($keywords[$i]['name']))) . '"';
}
return $hashes;
}
Expand Down
Loading

0 comments on commit eb64040

Please sign in to comment.