diff --git a/backend/app/cmd/avatar.go b/backend/app/cmd/avatar.go index 7321a09f..52174fe5 100644 --- a/backend/app/cmd/avatar.go +++ b/backend/app/cmd/avatar.go @@ -13,7 +13,8 @@ import ( ) // AvatarCommand set of flags and command for avatar migration -// it converts all avatarts from src.type to dst.type +// it converts all avatars from src.type to dst.type. +// Note: it is possible to run migration for the same types (src = dst) in order to resize all avatars. type AvatarCommand struct { AvatarSrc AvatarGroup `group:"src" namespace:"src"` AvatarDst AvatarGroup `group:"dst" namespace:"dst"` diff --git a/backend/app/store/avatar/bolt.go b/backend/app/store/avatar/bolt.go index 90ed197f..826a1ded 100644 --- a/backend/app/store/avatar/bolt.go +++ b/backend/app/store/avatar/bolt.go @@ -15,8 +15,8 @@ import ( ) // BoltDB implements avatar store with bolt -// using separate db (file) with "avatars" bucket to keep image bin and "metas" bucket to keep sha1 -// avatarID (base file name) used as a key +// using separate db (file) with "avatars" bucket to keep image bin and "metas" bucket +// to keep sha1 of picture. avatarID (base file name) used as a key for both. type BoltDB struct { fileName string // full path to boltdb resizeLimit int @@ -45,7 +45,7 @@ func NewBoltDB(fileName string, options bolt.Options, resizeLimit int) (*BoltDB, return &BoltDB{db: db, fileName: fileName, resizeLimit: resizeLimit}, nil } -// Put avatar to bolt, key by avatarID +// Put avatar to bolt, key by avatarID. Trying to resize image and lso calculates sha1 of the file for ID func func (b *BoltDB) Put(userID string, reader io.Reader) (avatar string, err error) { id := encodeID(userID) @@ -64,7 +64,8 @@ func (b *BoltDB) Put(userID string, reader io.Reader) (avatar string, err error) if err = tx.Bucket([]byte(avatarsBktName)).Put([]byte(avatarID), buf.Bytes()); err != nil { return errors.Wrapf(err, "can't put to bucket with %s", avatarID) } - return tx.Bucket([]byte(metasBktName)).Put([]byte(avatarID), []byte(b.sha1(buf.Bytes(), id))) + // store sha1 of the image + return tx.Bucket([]byte(metasBktName)).Put([]byte(avatarID), []byte(b.sha1(buf.Bytes(), avatarID))) }) return avatarID, err } @@ -87,16 +88,17 @@ func (b *BoltDB) Get(avatarID string) (reader io.ReadCloser, size int, err error func (b *BoltDB) ID(avatarID string) (id string) { data := []byte{} err := b.db.View(func(tx *bolt.Tx) error { - data = tx.Bucket([]byte(metasBktName)).Get([]byte(avatarID)) - if data == nil { + if data = tx.Bucket([]byte(metasBktName)).Get([]byte(avatarID)); data == nil { return errors.Errorf("can't load avatar's id for %s", avatarID) } return nil }) - if err != nil { + + if err != nil { // failed to get ID, use encoded avatarID log.Printf("[DEBUG] can't get avatar info '%s', %s", avatarID, err) return store.EncodeID(avatarID) } + return string(data) } diff --git a/backend/app/store/avatar/bolt_test.go b/backend/app/store/avatar/bolt_test.go index 4db0376e..b9ddac23 100644 --- a/backend/app/store/avatar/bolt_test.go +++ b/backend/app/store/avatar/bolt_test.go @@ -35,8 +35,9 @@ func TestBoltDB_PutAndGet(t *testing.T) { _, _, err = b.Get("bad avatar") assert.NotNil(t, err) + // check IDs assert.Equal(t, "fddae9ce556712a6ece0e8951a6e7a05c51ed6bf", b.ID(avatar)) - assert.Equal(t, "70c881d4a26984ddce795f6f71817c9cf4480e79", b.ID("aaaa"), "no data, encode avatar id") + assert.Equal(t, "70c881d4a26984ddce795f6f71817c9cf4480e79", b.ID("aaaa"), "no data, encoded avatar id") l, err := b.List() require.Nil(t, err) diff --git a/backend/app/store/avatar/store.go b/backend/app/store/avatar/store.go index a3876207..eb9a3aed 100644 --- a/backend/app/store/avatar/store.go +++ b/backend/app/store/avatar/store.go @@ -1,4 +1,5 @@ -// Package avatar defines store interface and implements local (fs) and gridfs (mongo) stores. +// Package avatar defines store interface and implements local (fs), gridfs (mongo) and boltdb stores. +// package avatar //go:generate sh -c "mockery -inpkg -name Store -print > /tmp/mock.tmp && mv /tmp/mock.tmp store_mock.go" @@ -32,7 +33,7 @@ type Store interface { ID(avatarID string) (id string) // unique id of stored avatar's data Remove(avatarID string) error // remove avatar data List() (ids []string, err error) // list all avatar ids - Close() error + Close() error // close store } // Migrate avatars between stores