mirror of
https://github.com/navidrome/navidrome.git
synced 2026-08-31 07:30:32 +00:00
feat(artwork): persist a thumbhash alongside the blurhash
The artwork table is content-addressed, so this costs one row per unique image rather than per entity. Measured on a 25k-image library: +0.6MB on a 727MB DB. The column is added to the existing add_artwork_tables migration rather than a new one, since #5847 has not been released and the table it extends ships in that same PR.
This commit is contained in:
parent
a4d979c49c
commit
313e93c3d9
@ -6,6 +6,7 @@ CREATE TABLE artwork (
|
||||
height INTEGER NOT NULL DEFAULT 0,
|
||||
size_bytes INTEGER NOT NULL DEFAULT 0,
|
||||
blur_hash TEXT NOT NULL DEFAULT '',
|
||||
thumb_hash TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ type Artwork struct {
|
||||
Height int `structs:"height"`
|
||||
SizeBytes int64 `structs:"size_bytes"`
|
||||
BlurHash string `structs:"blur_hash"`
|
||||
ThumbHash string `structs:"thumb_hash"`
|
||||
CreatedAt time.Time `structs:"created_at"`
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,8 @@ func (r *artworkRepository) PutImage(a *model.Artwork) error {
|
||||
}
|
||||
// created_at=excluded.created_at: reacquiring an orphan must reset the prune grace window.
|
||||
ins := Insert(r.tableName).SetMap(values).Suffix(`ON CONFLICT (hash) DO UPDATE SET mime=excluded.mime, width=excluded.width,
|
||||
height=excluded.height, size_bytes=excluded.size_bytes, blur_hash=excluded.blur_hash, created_at=excluded.created_at`)
|
||||
height=excluded.height, size_bytes=excluded.size_bytes, blur_hash=excluded.blur_hash,
|
||||
thumb_hash=excluded.thumb_hash, created_at=excluded.created_at`)
|
||||
_, err = r.executeSQL(ins)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -40,6 +40,25 @@ var _ = Describe("ArtworkRepository", func() {
|
||||
Expect(got.CreatedAt).ToNot(BeZero())
|
||||
})
|
||||
|
||||
It("round-trips the thumbhash alongside the blurhash", func() {
|
||||
a := &model.Artwork{Hash: "both1", Mime: "image/jpeg", BlurHash: "LKO2?U%2Tw=w", ThumbHash: "1QcSHQRnh493V4dIh4eXh1h4kJUI"}
|
||||
Expect(repo.PutImage(a)).To(Succeed())
|
||||
|
||||
got, err := repo.GetImage("both1")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(got.BlurHash).To(Equal("LKO2?U%2Tw=w"))
|
||||
Expect(got.ThumbHash).To(Equal("1QcSHQRnh493V4dIh4eXh1h4kJUI"))
|
||||
})
|
||||
|
||||
It("overwrites the thumbhash on re-acquisition", func() {
|
||||
Expect(repo.PutImage(&model.Artwork{Hash: "th2", Mime: "image/png", ThumbHash: "first"})).To(Succeed())
|
||||
Expect(repo.PutImage(&model.Artwork{Hash: "th2", Mime: "image/png", ThumbHash: "second"})).To(Succeed())
|
||||
|
||||
got, err := repo.GetImage("th2")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(got.ThumbHash).To(Equal("second"))
|
||||
})
|
||||
|
||||
It("is idempotent on Put (upsert by hash)", func() {
|
||||
a := &model.Artwork{Hash: "dup1", Mime: "image/png"}
|
||||
Expect(repo.PutImage(a)).To(Succeed())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user