go-latestver/internal/database/store.go

165 lines
4.6 KiB
Go
Raw Permalink Normal View History

2021-11-22 02:39:25 +00:00
package database
import (
"strings"
"time"
"github.com/pkg/errors"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/Luzifer/go-latestver/internal/version"
"github.com/Luzifer/go_helpers/v2/fieldcollection"
2021-11-22 02:39:25 +00:00
)
type (
// CatalogEntry represents the entry in the config file
2021-11-22 02:39:25 +00:00
CatalogEntry struct {
Name string `json:"name" yaml:"name"`
Tag string `json:"tag" yaml:"tag"`
Add PR testing, fix linter errors Squashed commit of the following: commit 2a83adf6c54d6abcf6762760fd38f2505511f545 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:34:49 2021 +0100 Lint: Fix copylocks errors Signed-off-by: Knut Ahlers <knut@ahlers.me> commit 418f85d504203a6968329e280ecd9cf7d2365373 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:31:38 2021 +0100 Lint: Fix gosec warnings Signed-off-by: Knut Ahlers <knut@ahlers.me> commit 1a977875740be3c40884aa0985578721ceb4ae37 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:28:02 2021 +0100 Lint: Disable gomnd for certain cases Signed-off-by: Knut Ahlers <knut@ahlers.me> commit 5e81cf79ba7256b321442530715a2b53de0a18e1 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:26:01 2021 +0100 Lint: fix ineffassign errors Signed-off-by: Knut Ahlers <knut@ahlers.me> commit cb14fae2dad985368e1f05d62f8e778817d01c6f Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:23:42 2021 +0100 Lint: Fix revive linter errors Signed-off-by: Knut Ahlers <knut@ahlers.me> commit b3390b8dff9b939caa4e3821a48dd848af0bfba4 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:21:35 2021 +0100 Lint: Remove unrequired dereference Signed-off-by: Knut Ahlers <knut@ahlers.me> commit f9052e6aa530c5b5017249fc6c31bdbb94252760 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 03:20:43 2021 +0100 Lint: Remove deadcode Signed-off-by: Knut Ahlers <knut@ahlers.me> commit 72b88adaa25a3bb5a7af21da7ed12f08cae36573 Author: Knut Ahlers <knut@ahlers.me> Date: Wed Dec 1 02:52:27 2021 +0100 Add PR-testing Signed-off-by: Knut Ahlers <knut@ahlers.me> Signed-off-by: Knut Ahlers <knut@ahlers.me>
2021-12-01 02:38:52 +00:00
Fetcher string `json:"-" yaml:"fetcher"`
FetcherConfig *fieldcollection.FieldCollection `json:"-" yaml:"fetcher_config"`
2021-11-22 02:39:25 +00:00
VersionConstraint *version.Constraint `json:"-" yaml:"version_constraint"`
2021-11-22 02:39:25 +00:00
Links []CatalogLink `json:"links" yaml:"links"`
}
// CatalogLink represents a link assigned to a CatalogEntry
2021-11-22 02:39:25 +00:00
CatalogLink struct {
IconClass string `json:"icon_class" yaml:"icon_class"`
Name string `json:"name" yaml:"name"`
URL string `json:"url" yaml:"url"`
}
// CatalogMeta contains meta-information about the catalog entry
2021-11-22 02:39:25 +00:00
CatalogMeta struct {
CatalogName string `gorm:"primaryKey" json:"-"`
CatalogTag string `gorm:"primaryKey" json:"-"`
CurrentVersion string `json:"current_version,omitempty"`
Error string `json:"error,omitempty"`
2021-11-22 02:39:25 +00:00
LastChecked *time.Time `json:"last_checked,omitempty"`
VersionTime *time.Time `json:"version_time,omitempty"`
}
// LogEntry represents a single version change for a given catalog entry
2021-11-22 02:39:25 +00:00
LogEntry struct {
CatalogName string `gorm:"index:catalog_key" json:"catalog_name"`
CatalogTag string `gorm:"index:catalog_key" json:"catalog_tag"`
Timestamp time.Time `gorm:"index:,sort:desc" json:"timestamp"`
VersionTo string `json:"version_to"`
VersionFrom string `json:"version_from"`
}
// CatalogMetaStore is an accessor for the meta store and wraps a Client
2021-11-22 02:39:25 +00:00
CatalogMetaStore struct {
c *Client
}
// LogStore is an accessor for the log store and wraps a Client
2021-11-22 02:39:25 +00:00
LogStore struct {
c *Client
}
)
// Key returns the name / tag combination as a single key
2021-11-22 02:39:25 +00:00
func (c CatalogEntry) Key() string { return strings.Join([]string{c.Name, c.Tag}, ":") }
// GetMeta fetches the current database stored CatalogMeta for the CatalogEntry
2021-11-22 02:39:25 +00:00
func (c CatalogMetaStore) GetMeta(ce *CatalogEntry) (*CatalogMeta, error) {
out := &CatalogMeta{
CatalogName: ce.Name,
CatalogTag: ce.Tag,
}
err := c.c.db.
Where(out).
First(out).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
// If there is no meta yet we just return empty meta
err = nil
}
return out, errors.Wrap(err, "querying metadata")
}
// Migrate applies the updated database schema for the CatalogMetaStore
func (c CatalogMetaStore) Migrate(dest *Client) error {
var metas []*CatalogMeta
if err := c.c.db.Find(&metas).Error; err != nil {
return errors.Wrap(err, "listing meta entries")
}
for _, m := range metas {
if err := dest.Catalog.PutMeta(m); err != nil {
return errors.Wrap(err, "storing meta to dest database")
}
}
return nil
}
// PutMeta stores the updated CatalogMeta
2021-11-22 02:39:25 +00:00
func (c CatalogMetaStore) PutMeta(cm *CatalogMeta) error {
return errors.Wrap(
c.c.db.Clauses(clause.OnConflict{UpdateAll: true}).Create(cm).Error,
"writing catalog meta",
)
}
func (c CatalogMetaStore) ensureTable() error {
return errors.Wrap(c.c.db.AutoMigrate(&CatalogMeta{}), "applying migration")
}
// Add creates a new LogEntry inside the LogStore
2021-11-22 02:39:25 +00:00
func (l LogStore) Add(le *LogEntry) error {
return errors.Wrap(
l.c.db.Create(le).Error,
"writing log entry",
)
}
// List retrieves unfiltered log entries by page
2021-11-22 02:39:25 +00:00
func (l LogStore) List(num, page int) ([]LogEntry, error) {
return l.listWithFilter(l.c.db, num, page)
}
// ListForCatalogEntry retrieves filered log entries by page
2021-11-22 02:39:25 +00:00
func (l LogStore) ListForCatalogEntry(ce *CatalogEntry, num, page int) ([]LogEntry, error) {
return l.listWithFilter(l.c.db.Where(&LogEntry{CatalogName: ce.Name, CatalogTag: ce.Tag}), num, page)
}
// Migrate applies the updated database schema for the LogStore
func (l LogStore) Migrate(dest *Client) error {
var logs []*LogEntry
if err := l.c.db.Find(&logs).Error; err != nil {
return errors.Wrap(err, "listing log entries")
}
for _, l := range logs {
if err := dest.Logs.Add(l); err != nil {
return errors.Wrap(err, "storing log to dest database")
}
}
return nil
}
func (LogStore) listWithFilter(filter *gorm.DB, num, page int) ([]LogEntry, error) {
2021-11-22 02:39:25 +00:00
var out []LogEntry
return out, errors.Wrap(
filter.
Order("timestamp desc").
Limit(num).Offset(num*page).
Find(&out).
Error,
"fetching log entries",
)
}
func (l LogStore) ensureTable() error {
return errors.Wrap(l.c.db.AutoMigrate(&LogEntry{}), "applying migration")
}