48 lines
2.0 KiB
Python
Executable File
48 lines
2.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
import argparse, hashlib, json
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
from pathlib import Path
|
|
|
|
def digest(p: Path):
|
|
h=hashlib.sha256()
|
|
with p.open("rb") as f:
|
|
for b in iter(lambda:f.read(1024*1024),b""):
|
|
h.update(b)
|
|
return p.stat().st_size,h.hexdigest()
|
|
|
|
def inventory(root: Path):
|
|
return {str(p.relative_to(root)):p for p in root.rglob("*.pbf") if p.is_file()}
|
|
|
|
def main():
|
|
ap=argparse.ArgumentParser()
|
|
ap.add_argument("mysql_root")
|
|
ap.add_argument("postgres_root")
|
|
ap.add_argument("--output",default="logs/mysql_postgresql_pbf_compare.json")
|
|
ap.add_argument("--workers",type=int,default=8)
|
|
args=ap.parse_args()
|
|
mr,pr=Path(args.mysql_root),Path(args.postgres_root)
|
|
mi,pi=inventory(mr),inventory(pr)
|
|
common=sorted(set(mi)&set(pi))
|
|
def one(rel):
|
|
ms,mh=digest(mi[rel]); ps,ph=digest(pi[rel])
|
|
return rel,ms,mh,ps,ph
|
|
identical=0; diffs=[]
|
|
with ThreadPoolExecutor(max_workers=args.workers) as ex:
|
|
for rel,ms,mh,ps,ph in ex.map(one,common):
|
|
if mh==ph and ms==ps: identical+=1
|
|
else: diffs.append({"path":rel,"mysql_bytes":ms,"postgres_bytes":ps,"mysql_sha256":mh,"postgres_sha256":ph})
|
|
out={
|
|
"mysql_root":str(mr.resolve()),"postgres_root":str(pr.resolve()),
|
|
"mysql_files":len(mi),"postgres_files":len(pi),"common_files":len(common),
|
|
"identical_files":identical,"different_files":len(diffs),
|
|
"mysql_only":sorted(set(mi)-set(pi)),"postgres_only":sorted(set(pi)-set(mi)),
|
|
"different_examples":diffs[:100],
|
|
"result":"PASS" if len(mi)==len(pi)==identical and not diffs else "DIFF",
|
|
}
|
|
op=Path(args.output);op.parent.mkdir(parents=True,exist_ok=True)
|
|
op.write_text(json.dumps(out,ensure_ascii=False,indent=2),encoding="utf-8")
|
|
print(json.dumps({k:v for k,v in out.items() if k not in ("mysql_only","postgres_only","different_examples")},ensure_ascii=False,indent=2))
|
|
print(f"report={op}")
|
|
if __name__=="__main__": main()
|