Store and compare file mtimes in nanoseconds (closes #226)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
The files table held mtime in whole seconds and the scanner compared whole seconds. A file rewritten with its size unchanged and a new mtime in the same second as the indexed one was treated as unchanged, and every later snapshot restored the old content. mtime is now stored as nanoseconds since the Unix epoch and compared at that precision. A local index written before this change holds seconds in mtime: its next backup re-chunks every file once, and a restore of a snapshot made before it sets mtimes near 1970. An mtime outside the years 1678 to 2262 does not fit in int64 nanoseconds; it is stored wrong and restored wrong. Model: opus-5-5
This commit is contained in:
@@ -54,16 +54,16 @@ func (r *FileRepository) Create(ctx context.Context, tx *sql.Tx, file *File) err
|
||||
if tx != nil {
|
||||
LogSQL("Execute", query,
|
||||
file.ID.String(), file.Path.String(), file.SourcePath.String(),
|
||||
file.MTime.Unix(), file.Size, file.Mode, file.UID, file.GID,
|
||||
file.MTime.UnixNano(), file.Size, file.Mode, file.UID, file.GID,
|
||||
file.LinkTarget.String())
|
||||
err = tx.QueryRowContext(ctx, query,
|
||||
file.ID.String(), file.Path.String(), file.SourcePath.String(),
|
||||
file.MTime.Unix(), file.Size, file.Mode, file.UID, file.GID,
|
||||
file.MTime.UnixNano(), file.Size, file.Mode, file.UID, file.GID,
|
||||
file.LinkTarget.String()).Scan(&idStr)
|
||||
} else {
|
||||
err = r.db.QueryRowWithLog(ctx, query,
|
||||
file.ID.String(), file.Path.String(), file.SourcePath.String(),
|
||||
file.MTime.Unix(), file.Size, file.Mode, file.UID, file.GID,
|
||||
file.MTime.UnixNano(), file.Size, file.Mode, file.UID, file.GID,
|
||||
file.LinkTarget.String()).Scan(&idStr)
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ func (r *FileRepository) ListModifiedSince(
|
||||
ORDER BY path
|
||||
`
|
||||
|
||||
rows, err := r.db.conn.QueryContext(ctx, query, since.Unix())
|
||||
rows, err := r.db.conn.QueryContext(ctx, query, since.UnixNano())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("querying files: %w", err)
|
||||
}
|
||||
@@ -392,7 +392,7 @@ func (r *FileRepository) CreateBatch(
|
||||
|
||||
args = append(args,
|
||||
f.ID.String(), f.Path.String(), f.SourcePath.String(),
|
||||
f.MTime.Unix(), f.Size, f.Mode, f.UID, f.GID,
|
||||
f.MTime.UnixNano(), f.Size, f.Mode, f.UID, f.GID,
|
||||
f.LinkTarget.String())
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ func (r *FileRepository) scanFileFrom(row fileRowScanner) (*File, error) {
|
||||
var (
|
||||
file File
|
||||
idStr, pathStr, sourcePathStr string
|
||||
mtimeUnix int64
|
||||
mtimeUnixNano int64
|
||||
linkTarget sql.NullString
|
||||
)
|
||||
|
||||
@@ -468,7 +468,7 @@ func (r *FileRepository) scanFileFrom(row fileRowScanner) (*File, error) {
|
||||
&idStr,
|
||||
&pathStr,
|
||||
&sourcePathStr,
|
||||
&mtimeUnix,
|
||||
&mtimeUnixNano,
|
||||
&file.Size,
|
||||
&file.Mode,
|
||||
&file.UID,
|
||||
@@ -487,7 +487,7 @@ func (r *FileRepository) scanFileFrom(row fileRowScanner) (*File, error) {
|
||||
file.Path = types.FilePath(pathStr)
|
||||
file.SourcePath = types.SourcePath(sourcePathStr)
|
||||
|
||||
file.MTime = time.Unix(mtimeUnix, 0).UTC()
|
||||
file.MTime = time.Unix(0, mtimeUnixNano).UTC()
|
||||
if linkTarget.Valid {
|
||||
file.LinkTarget = types.FilePath(linkTarget.String)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user