mirror of https://github.com/Xhofe/alist
				
				
				
			
		
			
				
	
	
		
			97 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
| package op
 | |
| 
 | |
| import (
 | |
| 	stdpath "path"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/Xhofe/go-cache"
 | |
| 	"github.com/alist-org/alist/v3/internal/db"
 | |
| 	"github.com/alist-org/alist/v3/internal/errs"
 | |
| 	"github.com/alist-org/alist/v3/internal/model"
 | |
| 	"github.com/alist-org/alist/v3/pkg/singleflight"
 | |
| 	"github.com/alist-org/alist/v3/pkg/utils"
 | |
| 	"github.com/pkg/errors"
 | |
| 	"gorm.io/gorm"
 | |
| )
 | |
| 
 | |
| var metaCache = cache.NewMemCache(cache.WithShards[*model.Meta](2))
 | |
| 
 | |
| // metaG maybe not needed
 | |
| var metaG singleflight.Group[*model.Meta]
 | |
| 
 | |
| func GetNearestMeta(path string) (*model.Meta, error) {
 | |
| 	return getNearestMeta(utils.FixAndCleanPath(path))
 | |
| }
 | |
| func getNearestMeta(path string) (*model.Meta, error) {
 | |
| 	meta, err := GetMetaByPath(path)
 | |
| 	if err == nil {
 | |
| 		return meta, nil
 | |
| 	}
 | |
| 	if errors.Cause(err) != errs.MetaNotFound {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	if path == "/" {
 | |
| 		return nil, errs.MetaNotFound
 | |
| 	}
 | |
| 	return getNearestMeta(stdpath.Dir(path))
 | |
| }
 | |
| 
 | |
| func GetMetaByPath(path string) (*model.Meta, error) {
 | |
| 	return getMetaByPath(utils.FixAndCleanPath(path))
 | |
| }
 | |
| func getMetaByPath(path string) (*model.Meta, error) {
 | |
| 	meta, ok := metaCache.Get(path)
 | |
| 	if ok {
 | |
| 		if meta == nil {
 | |
| 			return meta, errs.MetaNotFound
 | |
| 		}
 | |
| 		return meta, nil
 | |
| 	}
 | |
| 	meta, err, _ := metaG.Do(path, func() (*model.Meta, error) {
 | |
| 		_meta, err := db.GetMetaByPath(path)
 | |
| 		if err != nil {
 | |
| 			if errors.Is(err, gorm.ErrRecordNotFound) {
 | |
| 				metaCache.Set(path, nil)
 | |
| 				return nil, errs.MetaNotFound
 | |
| 			}
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		metaCache.Set(path, _meta, cache.WithEx[*model.Meta](time.Hour))
 | |
| 		return _meta, nil
 | |
| 	})
 | |
| 	return meta, err
 | |
| }
 | |
| 
 | |
| func DeleteMetaById(id uint) error {
 | |
| 	old, err := db.GetMetaById(id)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	metaCache.Del(old.Path)
 | |
| 	return db.DeleteMetaById(id)
 | |
| }
 | |
| 
 | |
| func UpdateMeta(u *model.Meta) error {
 | |
| 	u.Path = utils.FixAndCleanPath(u.Path)
 | |
| 	old, err := db.GetMetaById(u.ID)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	metaCache.Del(old.Path)
 | |
| 	return db.UpdateMeta(u)
 | |
| }
 | |
| 
 | |
| func CreateMeta(u *model.Meta) error {
 | |
| 	u.Path = utils.FixAndCleanPath(u.Path)
 | |
| 	metaCache.Del(u.Path)
 | |
| 	return db.CreateMeta(u)
 | |
| }
 | |
| 
 | |
| func GetMetaById(id uint) (*model.Meta, error) {
 | |
| 	return db.GetMetaById(id)
 | |
| }
 | |
| 
 | |
| func GetMetas(pageIndex, pageSize int) (metas []model.Meta, count int64, err error) {
 | |
| 	return db.GetMetas(pageIndex, pageSize)
 | |
| }
 |