First pass implementation of an SQLite backing store for fetched opportunities

This commit is contained in:
bwilliams committed 2026-10-13 12:52:17 +01:00
1 parent 9b0e6dccfe
commit 045492a148
29 files changed
+3132 -9

No files matched your search

+4
View File
@@ -34,6 +34,7 @@ is kept.
|---|---|---|---|
| `logging.level` | string | `warn` | One of `debug`, `info`, `warn`, `error` |
| `logging.file` | string | | Log file for `fetch service` (unless `--foreground`); other commands log to the terminal |
| `database.file` | string | | Path to the SQLite database file, used by the `migrate` commands |
| `sources.<source>.enabled` | bool | `false` | For every source |
| `sources.<source>.interval` | duration | `10m` | For every source; e.g. `30s`, `1h` |
| `sources.find_a_tender.api_root` | string | `https://www.find-tender.service.gov.uk/api/1.0` | URL of the Find a Tender API |
@@ -49,6 +50,8 @@ Example `config.yaml`:
logging:
level: info
file: ""
database:
file: ./jobsearch.db
sources:
find_a_tender:
enabled: true
@@ -126,6 +129,7 @@ Nothing in `section.go` needs changing.
| File | Contents |
|---|---|
| `config.go` | `JobSearchConfig`, defaults, Viper loading, text output |
| `conf_database.go` | `database` section |
| `load.go` | `Init`, `.env` and config file loading |
| `modify.go` | `StoreValue` and `PurgeValue` |
| `section.go` | The `Section` interface and the struct tag reflection shared by every section |
+35
View File
@@ -0,0 +1,35 @@
package config
import "reflect"
// JSCKDatabase is the database section's configuration key.
const JSCKDatabase string = "database"
// JobSearchConfigDatabase configures the SQLite database. File is the path to
// the database file.
type JobSearchConfigDatabase struct {
File string `cfg:"file"`
}
// ---------- Section methods (see Section) ----------
// Keys returns the keys directly in the section.
func (c *JobSearchConfigDatabase) Keys() []string { return keysOf(c) }
func (c JobSearchConfigDatabase) Map() map[string]any { return mapOf(c) }
func (c JobSearchConfigDatabase) Flatten() map[string]any {
return flattenOf(JSCKDatabase, c)
}
func (c JobSearchConfigDatabase) TypeOf(key string) (reflect.Kind, error) {
return typeOf(c, key)
}
func (c JobSearchConfigDatabase) ValueOf(key string) (any, error) {
return valueOf(c, key)
}
func (c *JobSearchConfigDatabase) SetValue(key string, value any) error {
return setValue(c, key, value)
}
+3 -2
View File
@@ -22,8 +22,9 @@ const EtcConfigPath string = "/etc/job-search"
// JobSearchConfig is the application's whole configuration, one field per
// section. Each field's cfg tag must match the section's JSCK* constant.
type JobSearchConfig struct {
Logging JobSearchConfigLogging `cfg:"logging"`
Sources JobSearchConfigSources `cfg:"sources"`
Logging JobSearchConfigLogging `cfg:"logging"`
Database JobSearchConfigDatabase `cfg:"database"`
Sources JobSearchConfigSources `cfg:"sources"`
}
// LoadDefaultConfig sets Viper's defaults from the configuration's default