fix(sqlite): actually always insert blocks for local files (fixes #10388) (#10411)

Due to a thinko, this optimisation was wildly incorrect and would read
to lack of block reuse when syncing files.

(We do not insert a blocklist per device, but only a single one. We
can't use the fact of whether the insert happened as a criteria for
inserting blocks.)

Signed-off-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
Jakob Borg
2025-09-23 15:46:31 +03:00
committed by GitHub
parent 932b4ce9bd
commit 6f0acacbd2
2 changed files with 43 additions and 2 deletions

View File

@@ -1206,6 +1206,47 @@ func TestOpenSpecialName(t *testing.T) {
db.Close()
}
func TestBlocksInserted(t *testing.T) {
// Verifies that blocks are inserted after syncing a file
t.Parallel()
sdb, err := Open(t.TempDir())
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := sdb.Close(); err != nil {
t.Fatal(err)
}
})
// Add remote file
files := []protocol.FileInfo{genFile("test1", 100, 1)}
if err := sdb.Update(folderID, protocol.DeviceID{42}, files); err != nil {
t.Fatal(err)
}
// Add the same file locally
if err := sdb.Update(folderID, protocol.LocalDeviceID, files); err != nil {
t.Fatal(err)
}
// Verify all the blocks are here
for i, block := range files[0].Blocks {
bs, err := itererr.Collect(sdb.AllLocalBlocksWithHash(folderID, block.Hash))
if err != nil {
t.Fatal(err)
}
if len(bs) == 0 {
t.Error("missing blocks for", i)
}
}
}
func mustCollect[T any](t *testing.T) func(it iter.Seq[T], errFn func() error) []T {
t.Helper()
return func(it iter.Seq[T], errFn func() error) []T {

View File

@@ -149,9 +149,9 @@ func (s *folderDB) Update(device protocol.DeviceID, fs []protocol.FileInfo) erro
if err != nil {
return wrap(err, "marshal blocklist")
}
if res, err := insertBlockListStmt.Exec(f.BlocksHash, bs); err != nil {
if _, err := insertBlockListStmt.Exec(f.BlocksHash, bs); err != nil {
return wrap(err, "insert blocklist")
} else if aff, _ := res.RowsAffected(); aff != 0 && device == protocol.LocalDeviceID {
} else if device == protocol.LocalDeviceID {
// Insert all blocks
if err := s.insertBlocksLocked(txp, f.BlocksHash, f.Blocks); err != nil {
return wrap(err, "insert blocks")