internal/index/index_meta.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | package index
import (
"encoding/json"
"os"
"time"
"go.alanpearce.eu/searchix/internal/file"
"go.alanpearce.eu/x/log"
"gitlab.com/tozd/go/errors"
)
const CurrentSchemaVersion = 4
type SourceMeta struct {
Updated time.Time
Path string
Rev string
ProgramsPath string
}
type data struct {
SchemaVersion int
Sources map[string]*SourceMeta
}
type Meta struct {
path string
log *log.Logger
data
}
func createMeta(path string, log *log.Logger) (*Meta, errors.E) {
exists, err := file.Exists(path)
if err != nil {
return nil, errors.WithMessage(err, "could not check for existence of index metadata")
}
if exists {
return nil, errors.New("index metadata already exists")
}
return &Meta{
path: path,
log: log,
data: data{
SchemaVersion: CurrentSchemaVersion,
},
}, nil
}
func openMeta(path string, log *log.Logger) (*Meta, errors.E) {
exists, err := file.Exists(path)
if err != nil {
return nil, errors.WithMessage(err, "could not check for existence of index metadata")
}
if !exists {
return createMeta(path, log)
}
j, baseErr := os.ReadFile(path)
if baseErr != nil {
return nil, errors.WithMessage(baseErr, "could not open index metadata file")
}
meta := Meta{
path: path,
log: log,
}
if err := json.Unmarshal(j, &meta.data); err != nil {
return nil, errors.WithMessage(err, "index metadata is corrupt, try replacing the index")
}
return &meta, nil
}
func (i *Meta) IsSchemaOutdated() bool {
return i.SchemaVersion < CurrentSchemaVersion
}
func (i *Meta) Save() errors.E {
i.SchemaVersion = CurrentSchemaVersion
j, err := json.Marshal(i.data)
if err != nil {
return errors.WithMessage(err, "could not prepare index metadata for saving")
}
i.log.Debug("saving index metadata", "path", i.path)
err = os.WriteFile(i.path, j, 0o600)
if err != nil {
return errors.WithMessage(err, "could not save index metadata")
}
return nil
}
func (i *Meta) GetSourceMeta(source string) *SourceMeta {
sourceMeta := i.Sources[source]
if sourceMeta == nil {
return &SourceMeta{}
}
return sourceMeta
}
func (i *Meta) SetSourceMeta(source string, meta *SourceMeta) {
if i.Sources == nil {
i.Sources = make(map[string]*SourceMeta)
}
i.Sources[source] = meta
}
func (i *Meta) LastUpdated() time.Time {
var last time.Time
for _, sourceMeta := range i.Sources {
if sourceMeta.Updated.After(last) {
last = sourceMeta.Updated
}
}
return last
}
|