Skip to content

Commit

Permalink
Make hound happy
Browse files Browse the repository at this point in the history
  • Loading branch information
aduffeck committed May 17, 2021
1 parent 7341f83 commit 97a79eb
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 54 deletions.
89 changes: 55 additions & 34 deletions pkg/storage/fs/owncloudsql/filecache/filecache.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ import (
"github.com/rs/zerolog/log"
)

// Cache represents a oc10-style file cache
type Cache struct {
driver string
db *sql.DB
}

// NewMysql returns a new Cache instance connecting to a MySQL database
func NewMysql(dsn string) (*Cache, error) {
sqldb, err := sql.Open("mysql", dsn)
if err != nil {
Expand All @@ -58,14 +60,16 @@ func NewMysql(dsn string) (*Cache, error) {
return New("mysql", sqldb)
}

// New returns a new Cache instance connecting to the given sql.DB
func New(driver string, sqldb *sql.DB) (*Cache, error) {
return &Cache{
driver: driver,
db: sqldb,
}, nil
}

func (c *Cache) GetNumericStorageId(id string) (int, error) {
// GetNumericStorageID returns the database id for the given storage
func (c *Cache) GetNumericStorageID(id string) (int, error) {
row := c.db.QueryRow("Select numeric_id from oc_storages where id = ?", id)
var nid int
switch err := row.Scan(&nid); err {
Expand All @@ -76,8 +80,9 @@ func (c *Cache) GetNumericStorageId(id string) (int, error) {
}
}

// File represents an entry of the file cache
type File struct {
Id int
ID int
Storage int
Parent int
MimePart int
Expand All @@ -94,28 +99,30 @@ type File struct {
Checksum string
}

// TrashItem represents a trash item of the file cache
type TrashItem struct {
Id int
ID int
Name string
User string
Path string
Timestamp int
}

// Scannable describes the interface providing a Scan method
type Scannable interface {
Scan(...interface{}) error
}

func (c *Cache) rowToFile(row Scannable) (*File, error) {
var fileid, storage, parent, mimetype, mimepart, size, mtime, storage_mtime, encrypted, unencrypted_size, permissions int
var fileid, storage, parent, mimetype, mimepart, size, mtime, storageMtime, encrypted, unencryptedSize, permissions int
var path, name, etag, checksum string
err := row.Scan(&fileid, &storage, &path, &parent, &permissions, &mimetype, &mimepart, &size, &mtime, &storage_mtime, &encrypted, &unencrypted_size, &name, &etag, &checksum)
err := row.Scan(&fileid, &storage, &path, &parent, &permissions, &mimetype, &mimepart, &size, &mtime, &storageMtime, &encrypted, &unencryptedSize, &name, &etag, &checksum)
if err != nil {
return nil, err
}

return &File{
Id: fileid,
ID: fileid,
Storage: storage,
Path: path,
Parent: parent,
Expand All @@ -124,30 +131,32 @@ func (c *Cache) rowToFile(row Scannable) (*File, error) {
MimePart: mimepart,
Size: size,
MTime: mtime,
StorageMTime: storage_mtime,
StorageMTime: storageMtime,
Encrypted: encrypted == 1,
UnencryptedSize: unencrypted_size,
UnencryptedSize: unencryptedSize,
Name: name,
Etag: etag,
Checksum: checksum,
}, nil
}

// Get returns the cache entry for the specified storage/path
func (c *Cache) Get(s interface{}, p string) (*File, error) {
storageId, err := toIntId(s)
storageID, err := toIntID(s)
if err != nil {
return nil, err
}

phashBytes := md5.Sum([]byte(p))
phash := hex.EncodeToString(phashBytes[:])

row := c.db.QueryRow("Select fileid, storage, path, parent, permissions, mimetype, mimepart, size, mtime, storage_mtime, encrypted, unencrypted_size, name, etag, checksum from oc_filecache where path_hash = ? and storage = ?", phash, storageId)
row := c.db.QueryRow("Select fileid, storage, path, parent, permissions, mimetype, mimepart, size, mtime, storage_mtime, encrypted, unencrypted_size, name, etag, checksum from oc_filecache where path_hash = ? and storage = ?", phash, storageID)
return c.rowToFile(row)
}

// Path returns the path for the specified entry
func (c *Cache) Path(id interface{}) (string, error) {
id, err := toIntId(id)
id, err := toIntID(id)
if err != nil {
return "", err
}
Expand All @@ -161,6 +170,7 @@ func (c *Cache) Path(id interface{}) (string, error) {
return path, 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)
if err != nil {
Expand All @@ -175,8 +185,9 @@ func (c *Cache) Permissions(storage interface{}, p string) (*provider.ResourcePe
return conversions.RoleFromOCSPermissions(perms).CS3ResourcePermissions(), nil
}

// InsertOrUpdate creates or updates a cache entry
func (c *Cache) InsertOrUpdate(storage interface{}, data map[string]interface{}) (int, error) {
storageId, err := toIntId(storage)
storageID, err := toIntID(storage)
if err != nil {
return -1, err
}
Expand All @@ -196,11 +207,11 @@ func (c *Cache) InsertOrUpdate(storage interface{}, data map[string]interface{})
if parentPath == "." {
parentPath = ""
}
parent, err := c.Get(storageId, parentPath)
parent, err := c.Get(storageID, parentPath)
if err != nil {
return -1, fmt.Errorf("could not find parent %s, %s, %v, %w", parentPath, path, parent, err)
}
data["parent"] = parent.Id
data["parent"] = parent.ID
data["name"] = filepath.Base(path)
if _, exists := data["checksum"]; !exists {
data["checksum"] = ""
Expand Down Expand Up @@ -274,12 +285,13 @@ func (c *Cache) InsertOrUpdate(storage interface{}, data map[string]interface{})
return int(id), nil
}

// Copy creates a copy of the specified entry at the target path
func (c *Cache) Copy(storage interface{}, sourcePath, targetPath string) (int, error) {
storageId, err := toIntId(storage)
storageID, err := toIntID(storage)
if err != nil {
return -1, err
}
source, err := c.Get(storageId, sourcePath)
source, err := c.Get(storageID, sourcePath)
if err != nil {
return -1, errors.Wrap(err, "could not find source")
}
Expand All @@ -306,17 +318,18 @@ func (c *Cache) Copy(storage interface{}, sourcePath, targetPath string) (int, e
return c.InsertOrUpdate(storage, data)
}

// Move moves the specified entry to the target path
func (c *Cache) Move(storage interface{}, sourcePath, targetPath string) error {
storageId, err := toIntId(storage)
storageID, err := toIntID(storage)
if err != nil {
return err
}
source, err := c.Get(storageId, sourcePath)
source, err := c.Get(storageID, sourcePath)
if err != nil {
return errors.Wrap(err, "could not find source")
}
newParentPath := strings.TrimRight(filepath.Dir(targetPath), "/")
newParent, err := c.Get(storageId, newParentPath)
newParent, err := c.Get(storageID, newParentPath)
if err != nil {
return errors.Wrap(err, "could not find new parent")
}
Expand All @@ -332,12 +345,15 @@ func (c *Cache) Move(storage interface{}, sourcePath, targetPath string) error {
}
defer stmt.Close()
phashBytes := md5.Sum([]byte(targetPath))
_, err = stmt.Exec(newParent.Id, targetPath, filepath.Base(targetPath), hex.EncodeToString(phashBytes[:]), storageId, source.Id)
_, err = stmt.Exec(newParent.ID, targetPath, filepath.Base(targetPath), hex.EncodeToString(phashBytes[:]), storageID, source.ID)
if err != nil {
return err
}

childRows, err := tx.Query("SELECT fileid, path from oc_filecache where parent = ?", source.Id)
childRows, err := tx.Query("SELECT fileid, path from oc_filecache where parent = ?", source.ID)
if err != nil {
return err
}
defer childRows.Close()
children := map[int]string{}
for childRows.Next() {
Expand All @@ -351,7 +367,7 @@ func (c *Cache) Move(storage interface{}, sourcePath, targetPath string) error {
for id, path := range children {
path = strings.Replace(path, sourcePath, targetPath, -1)
phashBytes = md5.Sum([]byte(path))
_, err = stmt.Exec(source.Id, path, filepath.Base(path), hex.EncodeToString(phashBytes[:]), storageId, id)
_, err = stmt.Exec(source.ID, path, filepath.Base(path), hex.EncodeToString(phashBytes[:]), storageID, id)
if err != nil {
tx.Rollback()
return err
Expand All @@ -361,6 +377,7 @@ func (c *Cache) Move(storage interface{}, sourcePath, targetPath string) error {
return tx.Commit()
}

// Delete removes the specified storage/path from the cache
func (c *Cache) Delete(storage interface{}, user, path, trashPath string) error {
err := c.Move(storage, path, trashPath)
if err != nil {
Expand Down Expand Up @@ -389,68 +406,72 @@ func (c *Cache) Delete(storage interface{}, user, path, trashPath string) error
return nil
}

// GetRecycleItem returns the specified recycle item
func (c *Cache) GetRecycleItem(user, path string, timestamp int) (*TrashItem, error) {
row := c.db.QueryRow("SELECT auto_id, id, location FROM oc_files_trash WHERE id = ? and user = ? and timestamp = ?", path, user, timestamp)
var autoid int
var autoID int
var id, location string
err := row.Scan(&autoid, &id, &location)
err := row.Scan(&autoID, &id, &location)
if err != nil {
return nil, err
}

return &TrashItem{
Id: autoid,
ID: autoID,
Name: id,
User: user,
Path: location,
Timestamp: timestamp,
}, nil
}

// PurgeRecycleItem deletes the specified item from the cache
func (c *Cache) PurgeRecycleItem(user, path string, timestamp int) error {
row := c.db.QueryRow("Select auto_id, location from oc_files_trash where id = ? and user = ? and timestamp = ?", path, user, timestamp)
var autoId int
var autoID int
var location string
err := row.Scan(&autoId, &location)
err := row.Scan(&autoID, &location)
if err != nil {
return err
}

_, err = c.db.Exec("DELETE FROM oc_files_trash WHERE auto_id=?", autoId)
_, err = c.db.Exec("DELETE FROM oc_files_trash WHERE auto_id=?", autoID)
if err != nil {
return err
}

storage, err := c.GetNumericStorageId("home::" + user)
storage, err := c.GetNumericStorageID("home::" + user)
if err != nil {
return err
}
item, err := c.Get(storage, filepath.Join("files_trashbin", "files", location, path+".d"+strconv.Itoa(timestamp)))
if err != nil {
return err
}
_, err = c.db.Exec("DELETE FROM oc_filecache WHERE fileid=? OR parent=?", item.Id, item.Id)
_, err = c.db.Exec("DELETE FROM oc_filecache WHERE fileid=? OR parent=?", item.ID, item.ID)

return err
}

// SetEtag set a new etag for the specified item
func (c *Cache) SetEtag(storage interface{}, path, etag string) error {
storageId, err := toIntId(storage)
storageID, err := toIntID(storage)
if err != nil {
return err
}
source, err := c.Get(storageId, path)
source, err := c.Get(storageID, path)
if err != nil {
return errors.Wrap(err, "could not find source")
}
stmt, err := c.db.Prepare("UPDATE oc_filecache SET etag=? WHERE storage = ? and fileid=?")
if err != nil {
return err
}
_, err = stmt.Exec(etag, storageId, source.Id)
_, err = stmt.Exec(etag, storageID, source.ID)
return err
}

// InsertMimetype adds a new mimetype to the database
func (c *Cache) InsertMimetype(mimetype string) error {
stmt, err := c.db.Prepare("INSERT INTO oc_mimetypes(mimetype) VALUES(?)")
if err != nil {
Expand All @@ -466,7 +487,7 @@ func (c *Cache) InsertMimetype(mimetype string) error {
return nil
}

func toIntId(rid interface{}) (int, error) {
func toIntID(rid interface{}) (int, error) {
switch t := rid.(type) {
case int:
return t, nil
Expand Down
10 changes: 5 additions & 5 deletions pkg/storage/fs/owncloudsql/filecache/filecache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ var _ = Describe("Filecache", func() {
os.Remove(testDbFile.Name())
})

Describe("GetNumericStorageId", func() {
Describe("GetNumericStorageID", func() {
It("returns the proper storage id", func() {
nid, err := cache.GetNumericStorageId("home::admin")
nid, err := cache.GetNumericStorageID("home::admin")
Expect(err).ToNot(HaveOccurred())
Expect(nid).To(Equal(1))
})
Expand All @@ -75,7 +75,7 @@ var _ = Describe("Filecache", func() {
file, err := cache.Get(1, path)
Expect(err).ToNot(HaveOccurred())
Expect(file).ToNot(BeNil())
Expect(file.Id).To(Equal(10))
Expect(file.ID).To(Equal(10))
Expect(file.Storage).To(Equal(1))
Expect(file.Path).To(Equal(path))
Expect(file.Parent).To(Equal(9))
Expand Down Expand Up @@ -268,7 +268,7 @@ var _ = Describe("Filecache", func() {
data["etag"] = "12345"
id, err := cache.InsertOrUpdate(1, data)
Expect(err).ToNot(HaveOccurred())
Expect(id).To(Equal(recordBefore.Id))
Expect(id).To(Equal(recordBefore.ID))

recordAfter, err := cache.Get(1, data["path"].(string))
Expect(err).ToNot(HaveOccurred())
Expand Down Expand Up @@ -443,7 +443,7 @@ var _ = Describe("Filecache", func() {

newEntry, err := cache.Get(1, "files_versions/Photos/Portugal.jpg.v1619528083")
Expect(err).ToNot(HaveOccurred())
Expect(newEntry.Id).ToNot(Equal(existingEntry.Id))
Expect(newEntry.ID).ToNot(Equal(existingEntry.ID))
Expect(newEntry.MimeType).To(Equal(existingEntry.MimeType))
})
})
Expand Down
Loading

0 comments on commit 97a79eb

Please sign in to comment.