Made each source start from its newest stored release, with --since as an override
Without --since, fetcher service and job-search serve start each source from the newest release stored for it (the new store.LatestReleaseDate, by Source), so a restart carries on where it left off instead of fetching the last day again; with nothing stored, the client's default still applies. --since overrides it for every source. The Find a Tender source's name is now a constant, as the Source its opportunities are stored with. The README's guide to adding a source is brought up to date with the current worker, start and config type names.
This commit is contained in:
1 parent
3c4fde8dfd
commit
284a589627
10 files changed
+256
-22
No files matched your search
@@ -23,6 +23,16 @@ package store
|
||||
const selectOpportunityLatestReleaseDate = `
|
||||
SELECT latest_release_date FROM opportunities WHERE uuid = ?`
|
||||
|
||||
// selectSourceLatestReleaseDate reads the newest latest_release_date of one
|
||||
// source's opportunities. ORDER BY rather than MAX keeps the column's DATETIME
|
||||
// type, so the driver reads it as a time; it walks the latest_release_date
|
||||
// index.
|
||||
const selectSourceLatestReleaseDate = `
|
||||
SELECT latest_release_date FROM opportunities
|
||||
WHERE source = ?
|
||||
ORDER BY latest_release_date DESC
|
||||
LIMIT 1`
|
||||
|
||||
// upsertOpportunity inserts or updates a opportunity. Named parameters
|
||||
// (types.Opportunity).
|
||||
//
|
||||
|
||||
@@ -33,6 +33,9 @@ var checks = map[string]queryCheck{
|
||||
"selectOpportunityLatestReleaseDate": {
|
||||
sql: selectOpportunityLatestReleaseDate,
|
||||
},
|
||||
"selectSourceLatestReleaseDate": {
|
||||
sql: selectSourceLatestReleaseDate,
|
||||
},
|
||||
"upsertOpportunity": {sql: upsertOpportunity, named: true},
|
||||
"selectOpportunityByUUID": {sql: selectOpportunityByUUID},
|
||||
"listOpportunitiesSelect": {
|
||||
|
||||
@@ -716,6 +716,26 @@ func (s *Store) ListReleases(
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
// LatestReleaseDate returns the date of the newest release stored for the
|
||||
// opportunities from source, or the zero time if none are stored, so a
|
||||
// fetcher can carry on from where it left off.
|
||||
func (s *Store) LatestReleaseDate(
|
||||
ctx context.Context, source string,
|
||||
) (time.Time, error) {
|
||||
var latest time.Time
|
||||
err := s.db.GetContext(ctx, &latest, selectSourceLatestReleaseDate, source)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return time.Time{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf(
|
||||
"reading the latest release date of %s: %w", source, err,
|
||||
)
|
||||
}
|
||||
|
||||
return latest, nil
|
||||
}
|
||||
|
||||
// ReleaseExists reports whether a release is already stored, so a fetcher
|
||||
// can skip converting it.
|
||||
func (s *Store) ReleaseExists(
|
||||
|
||||
@@ -837,3 +837,37 @@ func TestWonAndLostAreExclusive(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LatestReleaseDate is the newest release of one source's opportunities only,
|
||||
// and the zero time for a source with none stored.
|
||||
func TestLatestReleaseDate(t *testing.T) {
|
||||
s := openStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
latest, err := s.LatestReleaseDate(ctx, "FindATender")
|
||||
if err != nil || !latest.IsZero() {
|
||||
t.Fatalf("empty store: %v, %v; want the zero time", latest, err)
|
||||
}
|
||||
|
||||
mustSave(t, s, opportunity("ocds-1", "Older", 1, "r1"))
|
||||
mustSave(t, s, opportunity("ocds-2", "Newer", 5, "r1"))
|
||||
other := opportunity("ocds-3", "Another source's", 9, "r1")
|
||||
other.Source = "FTSMock"
|
||||
mustSave(t, s, other)
|
||||
|
||||
for source, uuid := range map[string]string{
|
||||
"FindATender": "ocds-2",
|
||||
"FTSMock": "ocds-3",
|
||||
} {
|
||||
want := mustGet(t, s, uuid).LatestReleaseDate
|
||||
latest, err := s.LatestReleaseDate(ctx, source)
|
||||
if err != nil || !latest.Equal(want) {
|
||||
t.Errorf("%s: %v, %v; want %v", source, latest, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
latest, err = s.LatestReleaseDate(ctx, "Nowhere")
|
||||
if err != nil || !latest.IsZero() {
|
||||
t.Errorf("unknown source: %v, %v; want the zero time", latest, err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user