Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions internal/server/postgres/dataserverimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,23 +245,39 @@ func (s *DataPlatformDataServiceServerImpl) DeleteForecast(

querier := db.New(ix.GetTxFromContext(ctx))

dfprms := db.DeleteForecastParams{
ForecastUuid: uuid.MustParse(req.ForecastUuid),
// Check the forecaster exists
pctprms := db.GetForecasterElseLatestParams{
ForecasterName: req.Forecaster.ForecasterName,
ForecasterVersion: req.Forecaster.ForecasterVersion,
}

err := querier.DeleteForecast(ctx, dfprms)
dbForecaster, err := querier.GetForecasterElseLatest(ctx, pctprms)
if err != nil {
l.Err(err).Msgf("querier.DeleteForecast(%+v)", dfprms)
l.Err(err).Msgf("querier.GetForecasterElseLatest(%+v)", pctprms)

return nil, status.Error(
codes.Internal,
"Backend communication error.",
codes.NotFound, "No such forecaster. "+
"Create the forecaster before submitting a forecast.",
)
}

l.Debug().
Str("dp.forecast.uuid", req.ForecastUuid).
Msg("deleted forecast")
// Delete the forecast
dfcprms := db.DeleteForecastParams{
ForecasterID: dbForecaster.ForecasterID,
GeometryUuid: uuid.MustParse(req.LocationUuid),
SourceTypeID: int16(req.EnergySource.Number()),
InitTimestamp: timeptrToPgTimestamp(req.InitTimeUtc),
}

err = querier.DeleteForecast(ctx, dfcprms)
if err != nil {
l.Err(err).Msgf("querier.DeleteForecast(%+v)", dfcprms)

return nil, status.Error(
codes.Internal,
"Could not delete forecast. Ensure the forecast exists.",
)
}

return &pb.DeleteForecastResponse{}, nil
}
Expand Down
17 changes: 13 additions & 4 deletions internal/server/postgres/dataserverimpl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1630,7 +1630,7 @@ func TestCreateForecast(t *testing.T) {

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
resp, err := dc.CreateForecast(t.Context(), tc.req)
_, err := dc.CreateForecast(t.Context(), tc.req)
if strings.Contains(tc.name, "Shouldn't") {
require.Error(t, err)
} else {
Expand All @@ -1649,7 +1649,10 @@ func TestCreateForecast(t *testing.T) {
require.NoError(t, err)
require.Equal(t, len(tc.req.Values), len(fResp.Values))
_, err = dc.DeleteForecast(t.Context(), &pb.DeleteForecastRequest{
ForecastUuid: resp.ForecastUuid,
Forecaster: fcResp.Forecaster,
LocationUuid: siteResp.LocationUuid,
EnergySource: pb.EnergySource_ENERGY_SOURCE_SOLAR,
InitTimeUtc: tc.req.InitTimeUtc,
})
require.NoError(t, err)

Expand Down Expand Up @@ -1886,7 +1889,7 @@ func BenchmarkPostgresClient(b *testing.B) {
})
b.Run(fmt.Sprintf("%d/CreateForecast", output.NumPgvs), func(b *testing.B) {
for b.Loop() {
resp, err := dc.CreateForecast(b.Context(), &pb.CreateForecastRequest{
_, err := dc.CreateForecast(b.Context(), &pb.CreateForecastRequest{
Forecaster: &pb.Forecaster{
ForecasterName: tc.NamePrefix + "_forecaster_1",
ForecasterVersion: "v1",
Expand All @@ -1902,7 +1905,13 @@ func BenchmarkPostgresClient(b *testing.B) {
})
require.NoError(b, err)
_, err = dc.DeleteForecast(b.Context(), &pb.DeleteForecastRequest{
ForecastUuid: resp.ForecastUuid,
Forecaster: &pb.Forecaster{
ForecasterName: tc.NamePrefix + "_forecaster_1",
ForecasterVersion: "v1",
},
LocationUuid: output.LocationUuids[0],
EnergySource: pb.EnergySource_ENERGY_SOURCE_SOLAR,
InitTimeUtc: timestamppb.New(pivotTime.Add(time.Duration(12+2) * time.Hour)),
})
require.NoError(b, err)
}
Expand Down
20 changes: 19 additions & 1 deletion internal/server/postgres/sql/queries/predictions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,28 @@ INSERT INTO pred.forecasts (
target_period,
metadata;

-- name: DeleteForecast :exec
-- name: DeleteForecastByUUID :exec
DELETE FROM pred.forecasts
WHERE forecast_uuid = $1;

-- name: DeleteForecast :exec
WITH forecasts_to_delete AS (
SELECT forecast_uuid FROM pred.forecasts AS f
WHERE f.forecast_uuid >= UUIDV7_BOUNDARY(sqlc.arg(init_timestamp)::TIMESTAMP)
AND f.forecast_uuid < UUIDV7_BOUNDARY(sqlc.arg(init_timestamp)::TIMESTAMP + INTERVAL '1 second')
AND f.geometry_uuid = $1
AND f.source_type_id = $2
AND f.forecaster_id = $3
),
deleted_values AS (
DELETE FROM pred.predicted_generation_values
WHERE target_time_utc >= sqlc.arg(init_timestamp)::TIMESTAMP
AND target_time_utc < sqlc.arg(init_timestamp)::TIMESTAMP + INTERVAL '3 days'
AND forecast_uuid IN (SELECT forecast_uuid FROM forecasts_to_delete)
)
DELETE FROM pred.forecasts
WHERE forecast_uuid IN (SELECT forecast_uuid FROM forecasts_to_delete);

-- name: CreatePredictedValues :copyfrom
/* CreatePredictedValues inserts predicted generation values using
* postgres COPY protocol, making it the fastest way to perform large inserts of predictions.
Expand Down
12 changes: 11 additions & 1 deletion proto/ocf/dp/dp-data.messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,20 @@ message CreateForecastResponse {


message DeleteForecastRequest {
string forecast_uuid = 1 [
string location_uuid = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.uuid = true
];
EnergySource energy_source = 2 [
(buf.validate.field).required = true
];
Forecaster forecaster = 3 [
(buf.validate.field).required = true
];
google.protobuf.Timestamp init_time_utc = 4 [
(buf.validate.field).required = true,
(buf.validate.field).timestamp = { gt: { seconds: 112000000}, lt_now: true }
];
}

message DeleteForecastResponse {}
Expand Down