(folder NoteFolder, abs string)
| 1087 | } |
| 1088 | |
| 1089 | func (v *Vault) readMeta(folder NoteFolder, abs string) (NoteMeta, error) { |
| 1090 | info, err := os.Stat(abs) |
| 1091 | if err != nil { |
| 1092 | return NoteMeta{}, err |
| 1093 | } |
| 1094 | rel, err := filepath.Rel(v.root, abs) |
| 1095 | if err != nil { |
| 1096 | return NoteMeta{}, err |
| 1097 | } |
| 1098 | relPosix := filepath.ToSlash(rel) |
| 1099 | statMtimeMs := mtimeMs(info) |
| 1100 | v.metaCacheMu.Lock() |
| 1101 | cached, ok := v.metaCache[abs] |
| 1102 | if ok && |
| 1103 | sameMtimeMs(cached.mtimeMs, statMtimeMs) && |
| 1104 | cached.size == info.Size() && |
| 1105 | cached.meta.Path == relPosix && |
| 1106 | cached.meta.Folder == folder { |
| 1107 | meta := cached.meta |
| 1108 | v.metaCacheMu.Unlock() |
| 1109 | return meta, nil |
| 1110 | } |
| 1111 | v.metaCacheMu.Unlock() |
| 1112 | |
| 1113 | body, err := os.ReadFile(abs) |
| 1114 | if err != nil { |
| 1115 | return NoteMeta{}, err |
| 1116 | } |
| 1117 | bodyStr := string(body) |
| 1118 | |
| 1119 | title := strings.TrimSuffix(filepath.Base(abs), filepath.Ext(abs)) |
| 1120 | |
| 1121 | meta := buildNoteMeta(relPosix, title, folder, info, bodyStr) |
| 1122 | v.metaCacheMu.Lock() |
| 1123 | v.metaCache[abs] = noteMetaCacheEntry{ |
| 1124 | mtimeMs: statMtimeMs, |
| 1125 | size: info.Size(), |
| 1126 | meta: meta, |
| 1127 | } |
| 1128 | v.metaCacheMu.Unlock() |
| 1129 | return meta, nil |
| 1130 | } |
| 1131 | |
| 1132 | func (v *Vault) ReadNote(rel string) (NoteContent, error) { |
| 1133 | v.mu.RLock() |
no test coverage detected