Ver Fonte

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 <[email protected]>
Jakob Borg há 3 semanas atrás
pai
commit
6f0acacbd2
2 ficheiros alterados com 43 adições e 2 exclusões
  1. 41 0
      internal/db/sqlite/db_test.go
  2. 2 2
      internal/db/sqlite/folderdb_update.go

+ 41 - 0
internal/db/sqlite/db_test.go

@@ -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 {

+ 2 - 2
internal/db/sqlite/folderdb_update.go

@@ -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")