134 lines
2.9 KiB
Go
134 lines
2.9 KiB
Go
package vfs
|
||
|
||
import (
|
||
"context"
|
||
"os"
|
||
"time"
|
||
|
||
db2 "gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
|
||
"gitlink.org.cn/cloudream/jcs-pub/client/internal/mount/fuse"
|
||
"gitlink.org.cn/cloudream/jcs-pub/client/internal/mount/vfs/cache"
|
||
clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
type FuseDir struct {
|
||
vfs *Vfs
|
||
pathComps []string
|
||
modTime time.Time
|
||
mode os.FileMode
|
||
}
|
||
|
||
func newDirFromCache(ch cache.CacheEntryInfo, vfs *Vfs) *FuseDir {
|
||
return &FuseDir{
|
||
vfs: vfs,
|
||
pathComps: ch.PathComps,
|
||
modTime: ch.ModTime,
|
||
mode: ch.Mode,
|
||
}
|
||
}
|
||
|
||
func (r *FuseDir) PathComps() []string {
|
||
return r.pathComps
|
||
}
|
||
|
||
func (r *FuseDir) Name() string {
|
||
return r.pathComps[len(r.pathComps)-1]
|
||
}
|
||
|
||
func (r *FuseDir) Size() int64 {
|
||
return 0
|
||
}
|
||
|
||
func (r *FuseDir) Mode() os.FileMode {
|
||
return os.ModeDir | r.mode
|
||
}
|
||
|
||
func (r *FuseDir) ModTime() time.Time {
|
||
info := r.vfs.cache.Stat(r.pathComps)
|
||
if info == nil {
|
||
return r.modTime
|
||
}
|
||
return info.ModTime
|
||
}
|
||
|
||
func (r *FuseDir) IsDir() bool {
|
||
return true
|
||
}
|
||
|
||
func (r *FuseDir) SetModTime(time time.Time) error {
|
||
dir := r.loadCacheDir()
|
||
if dir == nil {
|
||
return fuse.ErrNotExists
|
||
}
|
||
|
||
return dir.SetModTime(time)
|
||
}
|
||
|
||
// 如果不存在,应该返回ErrNotExists
|
||
func (r *FuseDir) Child(ctx context.Context, name string) (fuse.FsEntry, error) {
|
||
return child(r.vfs, ctx, r, name)
|
||
}
|
||
|
||
func (r *FuseDir) Children(ctx context.Context) ([]fuse.FsEntry, error) {
|
||
return listChildren(r.vfs, ctx, r)
|
||
}
|
||
|
||
func (r *FuseDir) ReadChildren() (fuse.DirReader, error) {
|
||
ens, err := listChildren(r.vfs, context.Background(), r)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return newFuseDirReader(ens), nil
|
||
}
|
||
|
||
func (r *FuseDir) NewDir(ctx context.Context, name string) (fuse.FsDir, error) {
|
||
return newDir(r.vfs, ctx, name, r)
|
||
}
|
||
|
||
func (r *FuseDir) NewFile(ctx context.Context, name string, flags uint32) (fuse.FileHandle, uint32, error) {
|
||
return newFile(r.vfs, ctx, name, r, flags)
|
||
}
|
||
|
||
func (r *FuseDir) RemoveChild(ctx context.Context, name string) error {
|
||
return removeChild(r.vfs, ctx, name, r)
|
||
}
|
||
|
||
func (r *FuseDir) MoveChild(ctx context.Context, oldName string, newName string, newParent fuse.FsDir) error {
|
||
return moveChild(r.vfs, ctx, oldName, r, newName, newParent.(FuseNode))
|
||
}
|
||
|
||
func (r *FuseDir) loadCacheDir() *cache.CacheDir {
|
||
var createOpt *cache.CreateDirOption
|
||
|
||
err := r.vfs.db.DoTx(func(tx db2.SQLContext) error {
|
||
pkg, err := r.vfs.db.Package().GetByFullName(tx, r.pathComps[0], r.pathComps[1])
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
err = r.vfs.db.Object().HasObjectWithPrefix(tx, pkg.PackageID, clitypes.JoinObjectPath(r.pathComps[2:]...))
|
||
if err == nil {
|
||
createOpt = &cache.CreateDirOption{
|
||
ModTime: time.Now(),
|
||
}
|
||
return nil
|
||
}
|
||
|
||
if err == gorm.ErrRecordNotFound {
|
||
return nil
|
||
}
|
||
|
||
return err
|
||
})
|
||
if err != nil {
|
||
return nil
|
||
}
|
||
|
||
return r.vfs.cache.LoadDir(r.pathComps, createOpt)
|
||
}
|
||
|
||
var _ fuse.FsDir = (*FuseDir)(nil)
|
||
var _ FuseNode = (*FuseDir)(nil)
|