@@ -157,6 +157,32 @@ func ListProductfiles(db *pgxpool.Pool, ID uuid.UUID, after string, before strin
157157 return ff , nil
158158}
159159
160+ // ListProductfilesLatestVersion returns ONE productfile per valid time over the range — the latest
161+ // forecast version for each datetime. A forecast product stores many issue-cycle versions of the
162+ // same valid time (version = the real reference/issue time), which would otherwise yield several
163+ // COGs per timestep; DISTINCT ON (datetime) ORDER BY version DESC keeps only the most-recent issue
164+ // for each. Observed products use the '1111-11-11..' sentinel version (one row per datetime already),
165+ // so this is effectively a pass-through for them. This is what the COG importer wants: one COG per
166+ // timestep, not every version.
167+ //
168+ // Note: bounded by the datetime range, but an index on (product_id, datetime, version DESC) would
169+ // make the DISTINCT ON cheap if this is ever run over very wide ranges.
170+ func ListProductfilesLatestVersion (db * pgxpool.Pool , ID uuid.UUID , after string , before string ) ([]Productfile , error ) {
171+ ff := make ([]Productfile , 0 )
172+ if err := pgxscan .Select (
173+ context .Background (), db , & ff ,
174+ `SELECT DISTINCT ON (datetime)
175+ product_id, id, datetime, file, version, acquirablefile_id
176+ FROM productfile
177+ WHERE product_id = $1 AND datetime >= $2 AND datetime <= $3
178+ ORDER BY datetime, version DESC` ,
179+ ID , after , before ,
180+ ); err != nil {
181+ return make ([]Productfile , 0 ), err
182+ }
183+ return ff , nil
184+ }
185+
160186func GetProductFileAvailability (db * pgxpool.Pool , ID uuid.UUID , interval string , d time.Time ) ([]ProductfileAvailability , error ) {
161187 avail := make ([]ProductfileAvailability , 0 )
162188 startTime := time .Date (d .Year (), d .Month (), d .Day (), 0 , 0 , 0 , 0 , d .Location ()).Format (time .RFC3339 )
0 commit comments