| | |
| | | for rows.Next() { |
| | | var st FileStat |
| | | var hash sql.NullString |
| | | if err := rows.Scan(&st.Path, &st.Size, &st.Mtime, &hash); err != nil { |
| | | var size, mtime sql.NullInt64 |
| | | // 旧库迁移到 v2 后,老行的 size/mtime/content_hash 为 NULL(ALTER ADD COLUMN 不带值)。 |
| | | // 用 Null 类型容忍 NULL:指纹缺失的行在对账时 size/mtime 必然不等,会走 |
| | | // sha256 二次确认并重新写入指纹,实现自愈,不会误判为"未变更"。 |
| | | if err := rows.Scan(&st.Path, &size, &mtime, &hash); err != nil { |
| | | return nil, err |
| | | } |
| | | st.Size = size.Int64 |
| | | st.Mtime = mtime.Int64 |
| | | st.ContentHash = hash.String |
| | | m[st.Path] = st |
| | | } |
| | |
| | | visited[id] = true |
| | | |
| | | query := ` |
| | | SELECT id, from_node, to_node, relation, label |
| | | SELECT id, from_node, to_node, relation, label, provenance |
| | | FROM edges |
| | | WHERE from_node = ? |
| | | ` |
| | |
| | | for rows.Next() { |
| | | var e graph.Edge |
| | | var edgeID int64 |
| | | if err := rows.Scan(&edgeID, &e.FromNode, &e.ToNode, &e.Relation, &e.Label); err != nil { |
| | | if err := rows.Scan(&edgeID, &e.FromNode, &e.ToNode, &e.Relation, &e.Label, &e.Provenance); err != nil { |
| | | rows.Close() |
| | | return nil, fmt.Errorf("扫描边失败: %w", err) |
| | | } |