When the database lay under a scanned operand, the walk recorded the database file, its -wal and -shm files and its .lock file like any other file, so every rescan updated them and report paired them with empty files. Once the database and the lock file are open, the scan now notes their device and inode, and the walk passes over a file with one of them, as an operand or below one, printing no line and counting nothing. Matching by device and inode holds through a symlinked directory, where comparing paths would not. A record an earlier scan left for one of them is deleted as unverified. README's smoke-test note on keeping the database out of the tree is gone, as it no longer holds. Judgement call: walkRules, in exclude.go, carries the noted files to the walk. Model: opus-5-5
This commit is contained in:
@@ -245,6 +245,42 @@ func openScanDatabase(ctx context.Context, path string) (*sql.DB, error) {
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// databaseFiles returns, by device and inode, the files of the database
|
||||
// at path that the scan keeps open: the database file, its -wal and
|
||||
// -shm files and its .lock file, each named from the database's path
|
||||
// with symlinks resolved, as SQLite and lockScanDatabase name them. The
|
||||
// scan calls it once the database and the lock file are open, so that
|
||||
// its walk passes over them however it reaches them, through a
|
||||
// symlinked directory included. A file that does not exist then is left
|
||||
// out, since no walk can reach it. There is no -journal file while the
|
||||
// database is in WAL mode.
|
||||
func databaseFiles(path string) ([]fileRec, error) {
|
||||
resolved, err := filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve database path: %w", err)
|
||||
}
|
||||
|
||||
var files []fileRec
|
||||
|
||||
for _, p := range []string{
|
||||
resolved, resolved + "-wal", resolved + "-shm", resolved + ".lock",
|
||||
} {
|
||||
fi, err := os.Lstat(p)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("database: %w", err)
|
||||
}
|
||||
|
||||
dev, ino := inodeOfInfo(fi)
|
||||
files = append(files, fileRec{path: p, dev: dev, ino: ino})
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
// closeScanDatabase switches the database at path from WAL back to
|
||||
// rollback-journal mode and closes it. Out of WAL mode the database
|
||||
// file alone holds the whole database, so a reader needs no -wal or
|
||||
|
||||
Reference in New Issue
Block a user