diff options
author | Alan Pearce | 2024-05-11 14:43:01 +0200 |
---|---|---|
committer | Alan Pearce | 2024-05-11 14:43:01 +0200 |
commit | 76f18d677b9b0bb70f701824e715f2ed10aeb8a0 (patch) | |
tree | 3ff2dadebde49f2042535c40f5832ebfa93d1b0b | |
parent | dbe952d1df63522e5c32b4ef3e59c43886ba9257 (diff) | |
download | searchix-76f18d677b9b0bb70f701824e715f2ed10aeb8a0.tar.lz searchix-76f18d677b9b0bb70f701824e715f2ed10aeb8a0.tar.zst searchix-76f18d677b9b0bb70f701824e715f2ed10aeb8a0.zip |
feat: version search index mapping schema and warn if outdated
-rw-r--r-- | internal/search/index_meta.go | 73 | ||||
-rw-r--r-- | internal/search/indexer.go | 34 | ||||
-rw-r--r-- | internal/search/search.go | 8 |
3 files changed, 110 insertions, 5 deletions
diff --git a/internal/search/index_meta.go b/internal/search/index_meta.go new file mode 100644 index 0000000..bb7e69f --- /dev/null +++ b/internal/search/index_meta.go @@ -0,0 +1,73 @@ +package search + +import ( + "encoding/json" + "log/slog" + "os" + "searchix/internal/file" + + "github.com/pkg/errors" +) + +const CurrentSchemaVersion = 1 + +type IndexMeta struct { + path string + SchemaVersion int +} + +func createMeta(path string) (*IndexMeta, error) { + 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 &IndexMeta{ + path: path, + SchemaVersion: CurrentSchemaVersion, + }, nil +} + +func openMeta(path string) (*IndexMeta, error) { + j, err := os.ReadFile(path) + if err != nil { + return nil, errors.WithMessage(err, "could not open index metadata file") + } + var meta IndexMeta + err = json.Unmarshal(j, &meta) + if err != nil { + return nil, errors.WithMessage(err, "index metadata is corrupt, try replacing the index") + } + + meta.checkSchemaVersion() + + return &meta, nil +} + +func (i *IndexMeta) checkSchemaVersion() { + if i.SchemaVersion < CurrentSchemaVersion { + slog.Warn( + "Index schema version out of date, suggest re-indexing", + "schema_version", + i.SchemaVersion, + "latest_version", + CurrentSchemaVersion, + ) + } +} + +func (i *IndexMeta) Save() error { + j, err := json.Marshal(i) + if err != nil { + return errors.WithMessage(err, "could not prepare index metadata for saving") + } + err = os.WriteFile(i.path, j, 0o600) + if err != nil { + return errors.WithMessage(err, "could not save index metadata") + } + + return nil +} diff --git a/internal/search/indexer.go b/internal/search/indexer.go index ea262ee..e2e23c2 100644 --- a/internal/search/indexer.go +++ b/internal/search/indexer.go @@ -28,6 +28,7 @@ import ( type WriteIndex struct { index bleve.Index + meta *IndexMeta } func createIndexMapping() (mapping.IndexMapping, error) { @@ -125,9 +126,13 @@ func createIndex(indexPath string) (bleve.Index, error) { return idx, nil } -const indexBaseName = "index.bleve" +const ( + indexBaseName = "index.bleve" + metaBaseName = "meta.json" +) var expectedDataFiles = []string{ + metaBaseName, indexBaseName, "sources", } @@ -137,6 +142,7 @@ func NewIndexer(dataRoot string, force bool) (*WriteIndex, error) { bleve.SetLog(log.Default()) indexPath := path.Join(dataRoot, indexBaseName) + metaPath := path.Join(dataRoot, metaBaseName) exists, err := file.Exists(indexPath) if err != nil { @@ -148,6 +154,7 @@ func NewIndexer(dataRoot string, force bool) (*WriteIndex, error) { } var idx bleve.Index + var meta *IndexMeta if !exists || force { if force { dir, err := os.ReadDir(dataRoot) @@ -171,18 +178,35 @@ func NewIndexer(dataRoot string, force bool) (*WriteIndex, error) { } } idx, err = createIndex(indexPath) + if err != nil { + return nil, err + } + + meta, err = createMeta(metaPath) + if err != nil { + return nil, err + } + + err = meta.Save() + if err != nil { + return nil, err + } } else { idx, err = bleve.Open(indexPath) if err != nil { - err = errors.WithMessagef(err, "could not open index at path %s", indexPath) + return nil, errors.WithMessagef(err, "could not open index at path %s", indexPath) } - } - if err != nil { - return nil, err + + meta, err = openMeta(metaPath) + if err != nil { + return nil, err + } + } return &WriteIndex{ idx, + meta, }, nil } diff --git a/internal/search/search.go b/internal/search/search.go index 357698c..829fefe 100644 --- a/internal/search/search.go +++ b/internal/search/search.go @@ -26,18 +26,26 @@ type Result struct { type ReadIndex struct { index bleve.Index + meta *IndexMeta } func Open(dataRoot string) (*ReadIndex, error) { indexPath := path.Join(dataRoot, indexBaseName) + metaPath := path.Join(dataRoot, metaBaseName) idx, err := bleve.Open(indexPath) if err != nil { return nil, errors.WithMessagef(err, "unable to open index at path %s", indexPath) } + meta, err := openMeta(metaPath) + if err != nil { + return nil, errors.WithMessagef(err, "unable to open metadata at path %s", metaPath) + } + return &ReadIndex{ idx, + meta, }, nil } |