备份(.rondbackup)与迷雾(.fwss)各加一层「先看差异再动手」: - 迷雾:上传先出差异页,说清叠加能补多少、整体替换会丢多少,并在真实底图上 用绿/灰/红标出会新增 / 不变 / 会丢的区域 - 备份:与当前数据集按 UUID 逐条比对(rond 每次导出都会重排 Z_PK,编号认不出人), 新增合入、冲突逐条选、仅站内有逐条勾选删除,全在一个事务里执行; 合入的行写回 entity_raw,保证再传同一份备份时差异归零 - 地点按坐标对齐:站点的「补全地址」会把地点改名,拿名称当键会让一整个地点的 到访全变成假冲突 - 附属数据(备注/结论/访客票/图片)从 dataset_id+src_pk 换成坐标键,换数据集不再失联; 访客票没有 dataset_id,回填按活跃数据集认领 - 修正 contentHash 拿 Z_PK 当指纹的隐患,以及两处「src_pk 跨快照稳定」的错误注释 导出格式(.rondbackup / .fwss)保持原样,往返测试通过。
90 lines
1.7 KiB
Go
90 lines
1.7 KiB
Go
// 一次性探针:验证 ZLOCATION.ZPLACEID / ZVISIT.ZEVENTIDENTIFIER 是否跨备份稳定。
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
|
||
"rond-with-you/internal/rond"
|
||
)
|
||
|
||
type snap struct {
|
||
placeID map[string]int
|
||
eventID map[string]int
|
||
nulls int
|
||
total int
|
||
evTotal int
|
||
}
|
||
|
||
func load(p string) *snap {
|
||
dir, err := os.MkdirTemp("", "colprobe")
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
defer os.RemoveAll(dir)
|
||
db, err := rond.Open(p, dir)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
defer db.Close()
|
||
s := &snap{placeID: map[string]int{}, eventID: map[string]int{}}
|
||
|
||
rows, err := db.Query(`SELECT Z_PK, COALESCE(ZPLACEID,'') FROM ZLOCATION`)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
for rows.Next() {
|
||
var pk int
|
||
var id string
|
||
rows.Scan(&pk, &id)
|
||
s.total++
|
||
if id == "" {
|
||
s.nulls++
|
||
} else {
|
||
s.placeID[id] = pk
|
||
}
|
||
}
|
||
rows.Close()
|
||
|
||
rows, err = db.Query(`SELECT COALESCE(ZEVENTIDENTIFIER,'') FROM ZVISIT`)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
for rows.Next() {
|
||
var id string
|
||
rows.Scan(&id)
|
||
if id != "" {
|
||
s.eventID[id] = 1
|
||
s.evTotal++
|
||
}
|
||
}
|
||
rows.Close()
|
||
fmt.Printf("%s: ZLOCATION %d 个(ZPLACEID 空 %d),ZEVENTIDENTIFIER 非空 %d\n",
|
||
p, s.total, s.nulls, s.evTotal)
|
||
return s
|
||
}
|
||
|
||
func main() {
|
||
a := load(os.Args[1])
|
||
b := load(os.Args[2])
|
||
inter, samePK := 0, 0
|
||
for k, pa := range a.placeID {
|
||
if pb, ok := b.placeID[k]; ok {
|
||
inter++
|
||
if pa == pb {
|
||
samePK++
|
||
}
|
||
}
|
||
}
|
||
fmt.Printf("\nZPLACEID 交集 %d(A 独有 %d,B 独有 %d),其中 Z_PK 相同 %d\n",
|
||
inter, len(a.placeID)-inter, len(b.placeID)-inter, samePK)
|
||
|
||
ei := 0
|
||
for k := range a.eventID {
|
||
if _, ok := b.eventID[k]; ok {
|
||
ei++
|
||
}
|
||
}
|
||
fmt.Printf("ZEVENTIDENTIFIER 交集 %d(A %d / B %d)\n", ei, len(a.eventID), len(b.eventID))
|
||
}
|