Skip to content

Commit 1ab286a

Browse files
authored
Merge pull request #449 from jjrom/develop
Correctly compute counts for catalog
2 parents 703d0c1 + 7779c4d commit 1ab286a

File tree

7 files changed

+61
-47
lines changed

7 files changed

+61
-47
lines changed

app/resto/core/RestoConstants.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class RestoConstants
2020
// [IMPORTANT] Starting resto 7.x, default routes are defined in RestoRouter class
2121

2222
// resto version
23-
const VERSION = '9.0.0-RC13';
23+
const VERSION = '9.0.0-RC14';
2424

2525
/* ============================================================
2626
* NEVER EVER TOUCH THESE VALUES

app/resto/core/RestoModel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ private function storeFeature($collection, $data, $params)
852852
* (do this before getKeywords to avoid iTag process)
853853
*/
854854
if (isset($productIdentifier) && (new FeaturesFunctions($collection->context->dbDriver))->featureExists($featureId, $collection->context->dbDriver->targetSchema . '.feature')) {
855-
RestoLogUtil::httpError(409, 'Feature ' . $featureId . ' (with productIdentifier=' . $productIdentifier . ') already in database');
855+
return RestoLogUtil::httpError(409, 'Feature ' . $featureId . ' (with productIdentifier=' . $productIdentifier . ') already in database');
856856
}
857857

858858
/*

app/resto/core/api/STACAPI.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ private function processPath($segments, $params = array())
13211321
}
13221322

13231323
$searchParams = array(
1324-
'q' => RestoUtil::path2ltree($catalogs[0]['id'])
1324+
'q' => $catalogs[0]['id']
13251325
);
13261326

13271327
foreach (array_keys($params) as $key) {

app/resto/core/dbfunctions/CatalogsFunctions.php

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featur
246246
$catalog['description'] ?? null,
247247
isset($catalog['id']) ? count(explode('/', $catalog['id'])) : 0,
248248
// If no input counter is specified - set to 1
249-
json_encode($counters, JSON_UNESCAPED_SLASHES),
249+
str_replace('[]', '{}', json_encode($counters, JSON_UNESCAPED_SLASHES)),
250250
$catalog['owner'] ?? $userid,
251251
json_encode($cleanLinks['links'], JSON_UNESCAPED_SLASHES),
252252
RestoConstants::GROUP_DEFAULT_ID,
@@ -426,8 +426,10 @@ public function updateCatalog($catalog, $userid, $baseUrl)
426426
$path = RestoUtil::path2ltree($catalog['id']);
427427

428428
/*
429-
* Add an entry in catalog_feature for each interalItems
429+
* Add an entry in catalog_feature for each interalItems but first remove all items !
430430
*/
431+
$this->removeCatalogFeatures($catalog['id']);
432+
431433
for ($i = 0, $ii = count($cleanLinks['internalItems']); $i < $ii; $i++) {
432434
$this->insertIntoCatalogFeature($cleanLinks['internalItems'][$i]['id'], $path, $catalog['id'], $cleanLinks['internalItems'][$i]['collection']);
433435
}
@@ -443,20 +445,19 @@ public function updateCatalog($catalog, $userid, $baseUrl)
443445
}
444446

445447
/**
446-
* Increment all catalogs relied to feature
448+
* Increment catalog counters
447449
*
448450
* @param string $featureId
449-
* @param string $collectionId
450451
* @param integer $increment
451452
*/
452-
public function updateFeatureCatalogsCounters($featureId, $collectionId, $increment)
453+
public function updateFeatureCatalogsCounters($featureId, $increment)
453454
{
454455

455456
$query = join(' ', array(
456-
'WITH path_hierarchy AS (SELECT distinct featureid, subpath(path, 0, generate_series(1, nlevel(path))) AS p FROM ' . $this->dbDriver->targetSchema . '.catalog_feature',
457+
'WITH path_hierarchy AS (SELECT collection, catalogid FROM ' . $this->dbDriver->targetSchema . '.catalog_feature',
457458
'WHERE featureid = \'' . pg_escape_string($this->dbDriver->getConnection(), $featureId) . '\')',
458-
'UPDATE ' . $this->dbDriver->targetSchema . '.catalog SET counters=public.increment_counters(counters,' . $increment . ',' . (isset($collectionId) ? '\'' . $collectionId . '\'': 'NULL') . ')',
459-
'WHERE lower(id) IN (SELECT LOWER(REPLACE(REPLACE(path_hierarchy.p::text, \'_\', \'.\'), \'.\', \'/\')) FROM path_hierarchy)'
459+
'UPDATE ' . $this->dbDriver->targetSchema . '.catalog SET counters=public.increment_counters(counters,' . $increment . ', (SELECT path_hierarchy.collection FROM path_hierarchy LIMIT 1))',
460+
'WHERE lower(id) IN (SELECT LOWER(path_hierarchy.catalogid) FROM path_hierarchy)'
460461
));
461462

462463
$results = $this->dbDriver->fetch($this->dbDriver->query($query));
@@ -524,6 +525,19 @@ public function removeCatalog($catalogId, $inTransaction = true)
524525

525526
}
526527

528+
/**
529+
* Remove features from a catalog i.e. unassociate feature from a catalog
530+
*
531+
* [WARNING] This DOES NOT REMOVE FEATURE IN TABLE feature
532+
*
533+
* @param string $catalogId
534+
*/
535+
private function removeCatalogFeatures($catalogId)
536+
{
537+
$this->dbDriver->query('UPDATE ' . $this->dbDriver->targetSchema . '.catalog SET counters=\'{"total":0, "collections":{}}\' WHERE lower(id) = lower(\'' . pg_escape_string($this->dbDriver->getConnection(), $catalogId) . '\')');
538+
$this->dbDriver->fetch($this->dbDriver->pQuery('DELETE FROM ' . $this->dbDriver->targetSchema . '.catalog_feature WHERE path = $1' , array(RestoUtil::path2ltree($catalogId)), 500, 'Cannot delete catalog_feature association for catalog ' . $catalogId));
539+
}
540+
527541
/**
528542
* Return STAC Summaries from catalogs elements from a type for a given collection
529543
*
@@ -665,15 +679,17 @@ private function insertIntoCatalogFeature($featureId, $path, $catalogId, $collec
665679
$path,
666680
$catalogId,
667681
$collectionId
668-
), 500, 'Cannot create association for ' . $featureId . ' intp catalog ' . $catalogId);
682+
), 500, 'Cannot create association for ' . $featureId . ' in catalog ' . $catalogId);
669683

670684
$this->dbDriver->pQuery('INSERT INTO ' . $this->dbDriver->targetSchema . '.catalog_feature (featureid, path, catalogid, collection) SELECT $1, $2::ltree, $3, $4 WHERE NOT EXISTS (SELECT 1 FROM ' . $this->dbDriver->targetSchema . '.catalog_feature WHERE featureid = $1 AND (path <@ $2::ltree OR path @> $2::ltree))', array(
671685
$featureId,
672686
$path,
673687
$catalogId,
674688
$collectionId
675-
), 500, 'Cannot create association for ' . $featureId . ' intp catalog ' . $catalogId);
689+
), 500, 'Cannot create association for ' . $featureId . ' in catalog ' . $catalogId);
676690

691+
$this->updateFeatureCatalogsCounters($featureId, 1);
692+
677693
}
678694

679695
/**
@@ -781,12 +797,17 @@ private function onTheFlyUpdateCountersWithCollection($catalog, $baseUrl)
781797
$originalLinks = json_decode($catalog['links'], true);
782798

783799
$collections = array();
784-
800+
785801
$results = $this->dbDriver->pQuery('SELECT id, counters, links FROM ' . $this->dbDriver->targetSchema . '.catalog WHERE lower(id) = lower($1) OR lower(id) LIKE lower($2) ORDER BY id ASC', array(
786802
$catalog['id'],
787803
$catalog['id'] . '/%'
788804
));
789805
while ($result = pg_fetch_assoc($results)) {
806+
807+
if ($catalog['id'] !== $result['id']) {
808+
$catalogCounters = json_decode($result['counters'], true);
809+
$counters['total'] = $counters['total'] + $catalogCounters['total'];
810+
}
790811

791812
// Process collection
792813
if ( isset($result['links']) ) {
@@ -808,14 +829,14 @@ private function onTheFlyUpdateCountersWithCollection($catalog, $baseUrl)
808829
'collections/' . $collectionId
809830
));
810831
while ($result = pg_fetch_assoc($results)) {
811-
$collectionCounter = json_decode($result['counters'], true);
812-
$counters['total'] = $counters['total'] + $collectionCounter['total'];
813-
$counters['collections'][$collectionId] = $collectionCounter['total'];
832+
$collectionCounters = json_decode($result['counters'], true);
833+
$counters['total'] = $counters['total'] + $collectionCounters['total'];
834+
$counters['collections'][$collectionId] = $collectionCounters['total'];
814835
for ($i = 0, $ii = count($originalLinks); $i < $ii; $i++) {
815836
if ($originalLinks[$i]['rel'] === 'child') {
816837
$exploded = explode('/', substr($originalLinks[$i]['href'], strlen($baseUrl . RestoRouter::ROUTE_TO_COLLECTIONS) + 1));
817838
if (count($exploded) === 1 && $exploded[0] === $collectionId) {
818-
$originalLinks[$i]['matched'] = $collectionCounter['total'];
839+
$originalLinks[$i]['matched'] = $collectionCounters['total'];
819840
if ( isset($result['title']) ) {
820841
$originalLinks[$i]['title'] = $result['title'];
821842
}

app/resto/core/dbfunctions/FeaturesFunctions.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ public function removeFeature($feature)
395395
/*
396396
* Update statistics counter for featureId - i.e. remove 1 per catalogs containing this feature
397397
*/
398-
$catalogsUpdated = (new CatalogsFunctions($this->dbDriver))->updateFeatureCatalogsCounters($feature->id, $feature->collection->id, -1);
398+
$catalogsUpdated = (new CatalogsFunctions($this->dbDriver))->updateFeatureCatalogsCounters($feature->id, -1);
399399

400400
/*
401401
* Next remove
@@ -500,7 +500,7 @@ public function updateFeature($feature, $collection, $newFeatureArray)
500500
* 2. Then delete resto.catalog_feature rows
501501
* 3. Then add resto.catalog_feature rows
502502
*/
503-
(new CatalogsFunctions($this->dbDriver))->updateFeatureCatalogsCounters($feature->id, $collection->id, -1);
503+
(new CatalogsFunctions($this->dbDriver))->updateFeatureCatalogsCounters($feature->id, -1);
504504

505505
$this->dbDriver->pQuery(
506506
'DELETE FROM ' . $this->dbDriver->targetSchema . '.catalog_feature WHERE featureid=$1', array(

app/resto/core/utils/JSONLDUtil.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public static function addDataCatalogMetadata($catalog)
8080

8181
if ( isset($catalog['extent'])) {
8282

83-
if ( isset($catalog['extent']['spatial']['bbox']) && is_array($catalog['extent']['spatial']['bbox']) ) {
83+
if ( isset($catalog['extent']['spatial']['bbox']) && is_array($catalog['extent']['spatial']['bbox']) && is_array($catalog['extent']['spatial']['bbox'][0]) ) {
8484
$jsonld['spatialCoverage'] = array(
8585
'@type' => 'Place',
8686
'geo' => array(
@@ -90,7 +90,7 @@ public static function addDataCatalogMetadata($catalog)
9090
);
9191
}
9292

93-
if ( isset($catalog['extent']['temporal']['interval']) && is_array($catalog['extent']['temporal']['interval']) ) {
93+
if ( isset($catalog['extent']['temporal']['interval']) && is_array($catalog['extent']['temporal']['interval']) && is_array($catalog['extent']['temporal']['interval'][0]) ) {
9494
$jsonld['temporalCoverage'] = join('/', array($catalog['extent']['temporal']['interval'][0][0] ?? '..', $catalog['extent']['temporal']['interval'][0][1] ?? '..'));
9595
}
9696

resto-database-model/01_resto_functions.sql

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -303,45 +303,38 @@ RETURNS JSON AS $$
303303
DECLARE
304304
-- Variable to store the total property from JSON
305305
total INTEGER;
306-
-- Variable to store individual keys and values from the collections array
307-
collection_key TEXT;
308-
collection_value INTEGER;
309306
-- Variable to store the updated collections array
310307
updated_collections JSONB;
311308
-- Variable to store the updated JSON object
312309
updated_counters JSONB;
313-
-- Boolean to check if collection_id exists
314-
collection_exists BOOLEAN := FALSE;
310+
-- Variable to store current value of the specific collection
311+
collection_value INTEGER;
315312
BEGIN
316313
-- Extract the total property from the JSON object
317314
total := (counters->>'total')::INTEGER;
318315

319-
-- Increment the total by the value
316+
-- Increment the total by the input value
320317
total := GREATEST(0, total + increment);
321318

322319
-- Initialize the updated collections as the original collections
323320
updated_collections := counters->'collections';
324321

325-
-- Check if collection_id is NULL
326-
IF collection_id IS NOT NULL THEN
327-
-- Loop through the collections array and update the collection_id value
328-
FOR collection_key, collection_value IN
329-
SELECT key, value::INTEGER
330-
FROM json_each_text(counters->'collections')
331-
LOOP
332-
IF collection_key = collection_id THEN
333-
-- Increment the collection value by the input value
334-
collection_value := GREATEST(0, collection_value + increment);
335-
-- Update the collections JSONB with the new value
336-
updated_collections := jsonb_set(updated_collections, ARRAY[collection_key], to_jsonb(collection_value));
337-
collection_exists := TRUE;
338-
END IF;
339-
END LOOP;
322+
-- Be sure to have collections:{} and not collections:[]
323+
IF jsonb_typeof(updated_collections) = 'array' THEN
324+
updated_collections := '{}';
325+
END IF;
340326

341-
-- If the collection_id does not exist, add it with the input value
342-
IF NOT collection_exists THEN
343-
updated_collections := jsonb_set(updated_collections, ARRAY[collection_id], to_jsonb(increment));
344-
END IF;
327+
-- Check if collection_id is NOT NULL and update the specific collection
328+
IF collection_id IS NOT NULL THEN
329+
-- Get the current value of the collection_id or default to 0 if it doesn't exist
330+
collection_value := COALESCE((counters->'collections'->>collection_id)::INTEGER, 0);
331+
332+
-- Increment the collection value
333+
collection_value := GREATEST(0, collection_value + increment);
334+
335+
-- Update the collections JSONB with the new value or insert a new one
336+
updated_collections := jsonb_set(updated_collections, ARRAY[collection_id], to_jsonb(collection_value));
337+
345338
END IF;
346339

347340
-- Update the JSON object with the new total and collections

0 commit comments

Comments
 (0)