Skip to content

Commit

Permalink
Use the information from the database for listing directories
Browse files Browse the repository at this point in the history
  • Loading branch information
aduffeck committed Jul 13, 2021
1 parent 8d38880 commit fc6c29d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 40 deletions.
35 changes: 35 additions & 0 deletions pkg/storage/fs/owncloudsql/filecache/filecache.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,38 @@ func (c *Cache) Path(id interface{}) (string, error) {
return path, nil
}

// List returns the list of entries below the given path
func (c *Cache) List(storage interface{}, p string) ([]*File, error) {
storageID, err := toIntID(storage)
if err != nil {
return nil, err
}

rows, err := c.db.Query(`
SELECT
fc.fileid, fc.storage, fc.path, fc.parent, fc.permissions, fc.mimetype, fc.mimepart,
mt.mimetype, fc.size, fc.mtime, fc.storage_mtime, fc.encrypted, fc.unencrypted_size,
fc.name, fc.etag, fc.checksum
FROM oc_filecache fc
LEFT JOIN oc_mimetypes mt ON fc.mimetype = mt.id
WHERE path != '' AND path LIKE ? AND PATH NOT LIKE ? AND storage = ?
`, p+"%", p+"%/%", storageID)
if err != nil {
return nil, err
}
defer rows.Close()
entries := []*File{}
for rows.Next() {
entry, err := c.rowToFile(rows)
if err != nil {
return nil, err
}
entries = append(entries, entry)
}

return entries, nil
}

// Permissions returns the permissions for the specified storage/path
func (c *Cache) Permissions(storage interface{}, p string) (*provider.ResourcePermissions, error) {
entry, err := c.Get(storage, p)
Expand All @@ -277,6 +309,9 @@ func (c *Cache) InsertOrUpdate(storage interface{}, data map[string]interface{})
defer func() { _ = tx.Rollback() }()

id, err := c.doInsertOrUpdate(tx, storage, data, false)
if err != nil {
return -1, err
}

err = tx.Commit()
if err != nil {
Expand Down
20 changes: 20 additions & 0 deletions pkg/storage/fs/owncloudsql/filecache/filecache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,26 @@ var _ = Describe("Filecache", func() {
})
})

Describe("List", func() {
It("lists all entries", func() {
list, err := cache.List(1, "")
Expect(err).ToNot(HaveOccurred())
Expect(len(list)).To(Equal(3))
})

It("filters", func() {
list, err := cache.List(1, "files_trashbin/")
Expect(err).ToNot(HaveOccurred())
Expect(len(list)).To(Equal(3))
})

It("filters deep", func() {
list, err := cache.List(1, "files/Photos/")
Expect(err).ToNot(HaveOccurred())
Expect(len(list)).To(Equal(3))
})
})

Describe("Path", func() {
It("returns the path", func() {
path, err := cache.Path(10)
Expand Down
82 changes: 42 additions & 40 deletions pkg/storage/fs/owncloudsql/owncloudsql.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,18 +564,7 @@ func (fs *ocfs) getUserStorage(ctx context.Context) (int, error) {
return id, err
}

func (fs *ocfs) convertToResourceInfo(ctx context.Context, fi os.FileInfo, ip string, sp string, mdKeys []string) (*provider.ResourceInfo, error) {
storage, err := fs.getStorage(ip)
if err != nil {
return nil, err
}

p := fs.toDatabasePath(ip)
cacheEntry, err := fs.filecache.Get(storage, p)
if err != nil {
return nil, err
}

func (fs *ocfs) convertToResourceInfo(ctx context.Context, entry *filecache.File, ip string, mdKeys []string) (*provider.ResourceInfo, error) {
mdKeysMap := make(map[string]struct{})
for _, k := range mdKeys {
mdKeysMap[k] = struct{}{}
Expand All @@ -586,16 +575,23 @@ func (fs *ocfs) convertToResourceInfo(ctx context.Context, fi os.FileInfo, ip st
returnAllKeys = true
}

var resourceType provider.ResourceType
isDir := entry.MimeTypeString == "httpd/unix-directory"
if isDir {
resourceType = provider.ResourceType_RESOURCE_TYPE_CONTAINER
} else {
resourceType = provider.ResourceType_RESOURCE_TYPE_FILE
}

ri := &provider.ResourceInfo{
Id: &provider.ResourceId{OpaqueId: strconv.Itoa(cacheEntry.ID)},
Path: sp,
Type: getResourceType(fi.IsDir()),
Etag: cacheEntry.Etag,
MimeType: mime.Detect(fi.IsDir(), ip),
Size: uint64(fi.Size()),
Id: &provider.ResourceId{OpaqueId: strconv.Itoa(entry.ID)},
Path: strings.TrimPrefix(entry.Path, "files/"),
Type: resourceType,
Etag: entry.Etag,
MimeType: entry.MimeTypeString,
Size: uint64(entry.Size),
Mtime: &types.Timestamp{
Seconds: uint64(fi.ModTime().Unix()),
// TODO read nanos from where? Nanos: fi.MTimeNanos,
Seconds: uint64(entry.MTime),
},
ArbitraryMetadata: &provider.ArbitraryMetadata{
Metadata: map[string]string{}, // TODO aduffeck: which metadata needs to go in here?
Expand All @@ -611,23 +607,17 @@ func (fs *ocfs) convertToResourceInfo(ctx context.Context, fi os.FileInfo, ip st
ri.PermissionSet = fs.permissionSet(ctx, ri.Owner)

// checksums
if !fi.IsDir() {
if !isDir {
if _, checksumRequested := mdKeysMap[checksumsKey]; returnAllKeys || checksumRequested {
// TODO which checksum was requested? sha1 adler32 or md5? for now hardcode sha1?
readChecksumIntoResourceChecksum(ctx, cacheEntry.Checksum, storageprovider.XSSHA1, ri)
readChecksumIntoOpaque(ctx, cacheEntry.Checksum, storageprovider.XSMD5, ri)
readChecksumIntoResourceChecksum(ctx, entry.Checksum, storageprovider.XSSHA1, ri)
readChecksumIntoOpaque(ctx, entry.Checksum, storageprovider.XSMD5, ri)
readChecksumIntoOpaque(ctx, ip, storageprovider.XSAdler32, ri)
}
}

return ri, nil
}
func getResourceType(isDir bool) provider.ResourceType {
if isDir {
return provider.ResourceType_RESOURCE_TYPE_CONTAINER
}
return provider.ResourceType_RESOURCE_TYPE_FILE
}

// GetPathByID returns the storage relative path for the file id, without the internal namespace
func (fs *ocfs) GetPathByID(ctx context.Context, id *provider.ResourceId) (string, error) {
Expand Down Expand Up @@ -1493,14 +1483,22 @@ func (fs *ocfs) listWithNominalHome(ctx context.Context, ip string, mdKeys []str
return nil, errors.Wrap(err, "owncloudsql: error reading permissions")
}

mds, err := ioutil.ReadDir(ip)
storage, err := fs.getStorage(ip)
if err != nil {
return nil, err
}
entries, err := fs.filecache.List(storage, fs.toDatabasePath(ip)+"/")
if err != nil {
return nil, errors.Wrapf(err, "owncloudsql: error listing %s", ip)
}
owner := fs.getOwner(ip)
finfos := []*provider.ResourceInfo{}
for _, md := range mds {
cp := filepath.Join(ip, md.Name())
m, err := fs.convertToResourceInfo(ctx, md, cp, fs.toStoragePath(ctx, cp), mdKeys)
for _, entry := range entries {
cp := filepath.Join(fs.c.DataDirectory, owner, entry.Path)
if err != nil {
return nil, err
}
m, err := fs.convertToResourceInfo(ctx, entry, cp, mdKeys)
if err != nil {
appctx.GetLogger(ctx).Error().Err(err).Str("path", cp).Msg("error converting to a resource info")
}
Expand Down Expand Up @@ -1536,15 +1534,19 @@ func (fs *ocfs) listHome(ctx context.Context, home string, mdKeys []string) ([]*
return nil, errors.Wrap(err, "owncloudsql: error reading permissions")
}

mds, err := ioutil.ReadDir(ip)
storage, err := fs.getStorage(ip)
if err != nil {
return nil, errors.Wrap(err, "owncloudsql: error listing files")
return nil, err
}

entries, err := fs.filecache.List(storage, fs.toDatabasePath(ip)+"/")
if err != nil {
return nil, errors.Wrapf(err, "owncloudsql: error listing %s", ip)
}
owner := fs.getOwner(ip)
finfos := []*provider.ResourceInfo{}
for _, md := range mds {
cp := filepath.Join(ip, md.Name())
m, err := fs.convertToResourceInfo(ctx, md, cp, fs.toStoragePath(ctx, cp), mdKeys)
for _, entry := range entries {
cp := filepath.Join(fs.c.DataDirectory, owner, entry.Path)
m, err := fs.convertToResourceInfo2(ctx, entry, cp, mdKeys)
if err != nil {
appctx.GetLogger(ctx).Error().Err(err).Str("path", cp).Msg("error converting to a resource info")
}
Expand All @@ -1553,7 +1555,7 @@ func (fs *ocfs) listHome(ctx context.Context, home string, mdKeys []string) ([]*

// list shadow_files
ip = fs.toInternalShadowPath(ctx, home)
mds, err = ioutil.ReadDir(ip)
mds, err := ioutil.ReadDir(ip)
if err != nil {
return nil, errors.Wrap(err, "owncloudsql: error listing shadow_files")
}
Expand Down

0 comments on commit fc6c29d

Please sign in to comment.