mirror of
https://github.com/navidrome/navidrome.git
synced 2026-01-03 06:15:22 +00:00
154 lines
3.7 KiB
Go
154 lines
3.7 KiB
Go
package persistence
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
. "github.com/Masterminds/squirrel"
|
|
"github.com/deluan/rest"
|
|
"github.com/navidrome/navidrome/model"
|
|
"github.com/pocketbase/dbx"
|
|
)
|
|
|
|
type pluginRepository struct {
|
|
sqlRepository
|
|
}
|
|
|
|
func NewPluginRepository(ctx context.Context, db dbx.Builder) model.PluginRepository {
|
|
r := &pluginRepository{}
|
|
r.ctx = ctx
|
|
r.db = db
|
|
r.registerModel(&model.Plugin{}, map[string]filterFunc{
|
|
"id": idFilter("plugin"),
|
|
"enabled": booleanFilter,
|
|
})
|
|
return r
|
|
}
|
|
|
|
func (r *pluginRepository) isPermitted() bool {
|
|
user := loggedUser(r.ctx)
|
|
return user.IsAdmin
|
|
}
|
|
|
|
func (r *pluginRepository) CountAll(options ...model.QueryOptions) (int64, error) {
|
|
if !r.isPermitted() {
|
|
return 0, rest.ErrPermissionDenied
|
|
}
|
|
sql := r.newSelect()
|
|
return r.count(sql, options...)
|
|
}
|
|
|
|
func (r *pluginRepository) Delete(id string) error {
|
|
if !r.isPermitted() {
|
|
return rest.ErrPermissionDenied
|
|
}
|
|
return r.delete(Eq{"id": id})
|
|
}
|
|
|
|
func (r *pluginRepository) Get(id string) (*model.Plugin, error) {
|
|
if !r.isPermitted() {
|
|
return nil, rest.ErrPermissionDenied
|
|
}
|
|
sel := r.newSelect().Where(Eq{"id": id}).Columns("*")
|
|
res := model.Plugin{}
|
|
err := r.queryOne(sel, &res)
|
|
return &res, err
|
|
}
|
|
|
|
func (r *pluginRepository) GetAll(options ...model.QueryOptions) (model.Plugins, error) {
|
|
if !r.isPermitted() {
|
|
return nil, rest.ErrPermissionDenied
|
|
}
|
|
sel := r.newSelect(options...).Columns("*")
|
|
res := model.Plugins{}
|
|
err := r.queryAll(sel, &res)
|
|
return res, err
|
|
}
|
|
|
|
func (r *pluginRepository) Put(plugin *model.Plugin) error {
|
|
if !r.isPermitted() {
|
|
return rest.ErrPermissionDenied
|
|
}
|
|
|
|
plugin.UpdatedAt = time.Now()
|
|
|
|
if plugin.ID == "" {
|
|
return errors.New("plugin ID cannot be empty")
|
|
}
|
|
|
|
// Upsert using INSERT ... ON CONFLICT for atomic operation
|
|
_, err := r.db.NewQuery(`
|
|
INSERT INTO plugin (id, path, manifest, config, enabled, last_error, sha256, created_at, updated_at)
|
|
VALUES ({:id}, {:path}, {:manifest}, {:config}, {:enabled}, {:last_error}, {:sha256}, {:created_at}, {:updated_at})
|
|
ON CONFLICT(id) DO UPDATE SET
|
|
path = excluded.path,
|
|
manifest = excluded.manifest,
|
|
config = excluded.config,
|
|
enabled = excluded.enabled,
|
|
last_error = excluded.last_error,
|
|
sha256 = excluded.sha256,
|
|
updated_at = excluded.updated_at
|
|
`).Bind(dbx.Params{
|
|
"id": plugin.ID,
|
|
"path": plugin.Path,
|
|
"manifest": plugin.Manifest,
|
|
"config": plugin.Config,
|
|
"enabled": plugin.Enabled,
|
|
"last_error": plugin.LastError,
|
|
"sha256": plugin.SHA256,
|
|
"created_at": time.Now(),
|
|
"updated_at": plugin.UpdatedAt,
|
|
}).Execute()
|
|
return err
|
|
}
|
|
|
|
func (r *pluginRepository) Count(options ...rest.QueryOptions) (int64, error) {
|
|
return r.CountAll(r.parseRestOptions(r.ctx, options...))
|
|
}
|
|
|
|
func (r *pluginRepository) EntityName() string {
|
|
return "plugin"
|
|
}
|
|
|
|
func (r *pluginRepository) NewInstance() any {
|
|
return &model.Plugin{}
|
|
}
|
|
|
|
func (r *pluginRepository) Read(id string) (any, error) {
|
|
return r.Get(id)
|
|
}
|
|
|
|
func (r *pluginRepository) ReadAll(options ...rest.QueryOptions) (any, error) {
|
|
return r.GetAll(r.parseRestOptions(r.ctx, options...))
|
|
}
|
|
|
|
func (r *pluginRepository) Save(entity any) (string, error) {
|
|
p := entity.(*model.Plugin)
|
|
if !r.isPermitted() {
|
|
return "", rest.ErrPermissionDenied
|
|
}
|
|
err := r.Put(p)
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return "", rest.ErrNotFound
|
|
}
|
|
return p.ID, err
|
|
}
|
|
|
|
func (r *pluginRepository) Update(id string, entity any, cols ...string) error {
|
|
p := entity.(*model.Plugin)
|
|
p.ID = id
|
|
if !r.isPermitted() {
|
|
return rest.ErrPermissionDenied
|
|
}
|
|
err := r.Put(p)
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return rest.ErrNotFound
|
|
}
|
|
return err
|
|
}
|
|
|
|
var _ model.PluginRepository = (*pluginRepository)(nil)
|
|
var _ rest.Repository = (*pluginRepository)(nil)
|
|
var _ rest.Persistable = (*pluginRepository)(nil)
|