From e5e680c68d6c56ea38d8d37bde4eefd7fb867939 Mon Sep 17 00:00:00 2001 From: Amund Isaksen <31344542+Teddy-1000@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:49:45 +0200 Subject: [PATCH] Restore lost code (#199) * Restore lost code * Remove old line --- .../storagebackend/postgresql/getextents.go | 111 +++++++++--------- protobuf/datastore.proto | 10 +- 2 files changed, 57 insertions(+), 64 deletions(-) diff --git a/datastore/datastore/storagebackend/postgresql/getextents.go b/datastore/datastore/storagebackend/postgresql/getextents.go index 4b9d5fa8..a445f4e4 100644 --- a/datastore/datastore/storagebackend/postgresql/getextents.go +++ b/datastore/datastore/storagebackend/postgresql/getextents.go @@ -5,79 +5,80 @@ import ( "datastore/common" "datastore/datastore" "fmt" + "time" _ "github.com/lib/pq" "google.golang.org/grpc/codes" "google.golang.org/protobuf/types/known/timestamppb" ) -// createExtQueryVals creates from request values used for querying extensions. -// -// Values to be used for query placeholders are appended to phVals. -// -// Returns: -// - time filter used in a 'WHERE ... AND ...' clause -// - filter for reflectable metadata fields of type int64 ... ditto -// - filter for reflectable metadata fields of type string ... ditto -func createExtQueryVals(request *datastore.GetExtentsRequest, phVals *[]interface{}) ( - string, string, string) { +// getTemporalExtent gets the current temporal extent of all observations in the storage. +func getTemporalExtent(db *sql.DB) (*datastore.TimeInterval, error) { + query := "SELECT min(obstime_instant), max(obstime_instant) FROM observation" + row := db.QueryRow(query) - loTime, hiTime := common.GetValidTimeRange() - timeFilter := fmt.Sprintf(` - ((obstime_instant >= to_timestamp(%d)) AND (obstime_instant <= to_timestamp(%d))) - `, loTime.Unix(), hiTime.Unix()) + var start, end time.Time + + err := row.Scan(&start, &end) + if err != nil { + return nil, fmt.Errorf("row.Scan() failed: %v", err) + } - int64MdataFilter := getInt64MdataFilter(request.GetFilter(), phVals) - stringMdataFilter := getStringMdataFilter(request.GetFilter(), phVals) + loTime, hiTime := common.GetValidTimeRange() + if start.Before(loTime) { + start = loTime + } + if end.After(hiTime) { + end = hiTime + } - return timeFilter, int64MdataFilter, stringMdataFilter + return &datastore.TimeInterval{ + Start: timestamppb.New(start), + End: timestamppb.New(end), + }, nil } -// GetExtents ... (see documentation in StorageBackend interface) -func (sbe *PostgreSQL) GetExtents(request *datastore.GetExtentsRequest) ( - *datastore.GetExtentsResponse, codes.Code, string) { +// getSpatialExtent gets the current horizontally spatial extent of all observations in the storage. +func getSpatialExtent(db *sql.DB) (*datastore.BoundingBox, error) { + query := ` + SELECT ST_XMin(ext), ST_YMin(ext), ST_XMax(ext), ST_YMax(ext) + FROM (SELECT ST_Extent(point::geometry) AS ext FROM geo_point) t + ` + row := db.QueryRow(query) + + var xmin, ymin, xmax, ymax float64 - // get values needed for query - phVals := []interface{}{} // placeholder values - timeFilter, int64MdataFilter, stringMdataFilter := createExtQueryVals(request, &phVals) + err := row.Scan(&xmin, &ymin, &xmax, &ymax) + if err != nil { + return nil, fmt.Errorf("row.Scan() failed: %v", err) + } - query := fmt.Sprintf(` - SELECT temp_min, temp_max, - ST_XMin(spat_ext), ST_YMin(spat_ext), ST_XMax(spat_ext), ST_YMax(spat_ext) - FROM ( - SELECT min(obstime_instant) AS temp_min, max(obstime_instant) AS temp_max, - ST_Extent(point::geometry) AS spat_ext - FROM observation - JOIN time_series ON observation.ts_id = time_series.id - JOIN geo_point ON observation.geo_point_id = geo_point.id - WHERE %s AND %s AND %s - ) t - `, timeFilter, int64MdataFilter, stringMdataFilter) + return &datastore.BoundingBox{ + Left: xmin, + Bottom: ymin, + Right: xmax, + Top: ymax, + }, nil +} - row := sbe.Db.QueryRow(query, phVals...) +// GetExtents ... (see documentation in StorageBackend interface) +func (sbe *PostgreSQL) GetExtents(_ *datastore.GetExtentsRequest) ( + *datastore.GetExtentsResponse, codes.Code, string, +) { + var err error - var ( - start, end sql.NullTime - xmin, ymin, xmax, ymax float64 - ) + temporalExtent, err := getTemporalExtent(sbe.Db) + if err != nil { + return nil, codes.Internal, fmt.Sprintf("getTemporalExtent() failed: %v", err) + } - err := row.Scan(&start, &end, &xmin, &ymin, &xmax, &ymax) - if !start.Valid { // indicates no matching rows found! - return nil, codes.NotFound, "no matching data to compute extensions for" - } else if err != nil { - return nil, codes.Internal, fmt.Sprintf("row.Scan() failed: %v", err) + spatialExtent, err := getSpatialExtent(sbe.Db) + if err != nil { + return nil, codes.Internal, fmt.Sprintf("getSpatialExtent() failed: %v", err) } return &datastore.GetExtentsResponse{ - TemporalExtent: &datastore.TimeInterval{ - Start: timestamppb.New(start.Time), - End: timestamppb.New(end.Time), - }, - SpatialExtent: &datastore.BoundingBox{ - Left: xmin, - Bottom: ymin, - Right: xmax, - Top: ymax, - }, + TemporalExtent: temporalExtent, + SpatialExtent: spatialExtent, }, codes.OK, "" } diff --git a/protobuf/datastore.proto b/protobuf/datastore.proto index 42eb5f4b..b9c61575 100644 --- a/protobuf/datastore.proto +++ b/protobuf/datastore.proto @@ -305,15 +305,7 @@ message GetTSAGResponse { //--------------------------------------------------------------------------- message GetExtentsRequest { - // --- BEGIN filter for reflectable metadata of type int64 or string ------------------------- - - // general filter - // - map keys must correspond exactly with string field names in TSMetadata or ObsMetadata - // - if map key F is specified (where F is for example 'platform'), only observations that match - // at least one of these values for F may be returned - map filter = 1; - - // --- END filter for reflectable metadata of type int64 or string ------------------------- + // No parameters } message GetExtentsResponse {