#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""fix_delete_wholesite.py —— 去掉 2 个脚本的「整站清空再重灌」DELETE

理由（2026-09-25 QC）：
  * database is locked：大事务 + 日跑并发 → 间歇崩（实测 luanxian 60% / quanjiao 53% 失败）
  * 更危险：中途死掉（超时/异常）会把整个站的数据清空
  * page_url 有 UNIQUE 索引 (idx_gov_raw_page_url)，且两脚本分别用
    INSERT OR IGNORE / INSERT OR REPLACE → 本来就幂等，DELETE 是多余且致命的
替代：加 PRAGMA busy_timeout=60000 + 去掉两条 DELETE
"""
import ast
import os
import shutil
import sqlite3
import sys

D = "/root/gov_crawler/"
BAKDIR = D + "Archive/"

CASES = [
    ("crawl_luanxian_854.py", "滦州市人民政府-服务事项", '''    conn = sqlite3.connect(DB_PATH, timeout=60)
    cur = conn.cursor()
    cur.execute("DELETE FROM gov_search WHERE site_name=?", (SITE_NAME,))
    cur.execute("DELETE FROM gov_raw WHERE site_name=?", (SITE_NAME,))
    conn.commit()
    print("[清理] 已清理旧数据", flush=True)''',
     '''    conn = sqlite3.connect(DB_PATH, timeout=60)
    conn.execute("PRAGMA busy_timeout=60000")
    cur = conn.cursor()
    # 2026-09-25 QC 修复：去掉「整站清空再重灌」的两条 DELETE。
    # 原写法大事务 + 日跑并发 → sqlite3.OperationalError: database is locked（实测失败率 60%），
    # 且中途死掉会把整站数据清空。page_url 有 UNIQUE 索引(idx_gov_raw_page_url)，
    # 本脚本用 INSERT OR IGNORE，本身就幂等，不会产生重复。
    print("[清理] 已跳过整站删除（改为幂等插入）", flush=True)'''),
    ("crawl_quanjiao_tzgg.py", "全椒县人民政府-通知公告", '''    conn = sqlite3.connect(db_path, timeout=60)
    c = conn.cursor()
    
    c.execute("DELETE FROM gov_search WHERE rowid IN (SELECT id FROM gov_raw WHERE site_name=?)", (SITE_NAME,))
    c.execute("DELETE FROM gov_raw WHERE site_name=?", (SITE_NAME,))
    conn.commit()
    print(f"已清理旧数据")''',
     '''    conn = sqlite3.connect(db_path, timeout=60)
    conn.execute("PRAGMA busy_timeout=60000")
    c = conn.cursor()
    # 2026-09-25 QC 修复：去掉整站 DELETE（同 crawl_luanxian_854.py 的理由）。
    # 本脚本用 INSERT OR REPLACE，page_url UNIQUE 索引保证幂等更新。
    print(f"已跳过整站删除（改为幂等 REPLACE）")'''),
]

db = sqlite3.connect("file:/root/search.db?mode=ro", uri=True, timeout=30)
for f, site, old, new in CASES:
    p = D + f
    print("=" * 90)
    print("【%s】站点=%s" % (f, site))
    n = db.execute("SELECT COUNT(*) FROM gov_raw WHERE site_name=?", (site,)).fetchone()[0]
    print("  修前库内行数: %d（修后重跑必须仍 >= 此值，否则数据丢失）" % n)
    src = open(p, encoding="utf-8").read()
    if "整站" in src or "busy_timeout" in src:
        print("  ⚠️ 该文件已有修复痕迹，跳过")
        continue
    if src.count(old) != 1:
        print("  ❌ 锚点命中 %d 次，跳过" % src.count(old))
        continue
    src2 = src.replace(old, new)
    try:
        ast.parse(src2)
    except SyntaxError as e:
        print("  ❌ 语法错误，未落盘:", e)
        continue
    os.makedirs(BAKDIR, exist_ok=True)
    bak = BAKDIR + f + ".bak_20260925_delwholesite"
    if not os.path.exists(bak):
        shutil.copy2(p, bak)
    open(p, "w", encoding="utf-8").write(src2)
    print("  ✅ 已修（备份 %s）" % os.path.basename(bak))
db.close()
