Spaces:
Runtime error
Runtime error
File size: 4,438 Bytes
c24ccd9 ae31e87 c24ccd9 ae31e87 8f82127 c24ccd9 ae31e87 c24ccd9 ae31e87 8f82127 709e953 ae31e87 1023d6e ae31e87 c24ccd9 8f82127 c24ccd9 1023d6e c24ccd9 ae31e87 1023d6e c24ccd9 1023d6e ae31e87 8f82127 c24ccd9 ae31e87 c24ccd9 ae31e87 c24ccd9 8f82127 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | # src/db.py — SQLite helpers (HF Spaces-friendly)
from __future__ import annotations
import os, shutil, sqlite3
from pathlib import Path
# Canonical schema lives in repo
REPO_DIR = Path(__file__).resolve().parents[1]
CANONICAL_SCHEMA = REPO_DIR / "src" / "schema.sql"
# Writable defaults on HF Spaces
DEFAULT_DB = Path("/tmp/pol_indexer.sqlite")
DEFAULT_SCHEMA = Path("/tmp/schema.sql")
def _is_writable(p: Path) -> bool:
try:
p.parent.mkdir(parents=True, exist_ok=True)
test = p.parent / ".write_test"
test.write_text("ok", encoding="utf-8")
test.unlink(missing_ok=True)
return True
except Exception:
return False
# Resolve DB_PATH
_env_db = os.getenv("DB_PATH")
DB_PATH = Path(_env_db).resolve() if _env_db else DEFAULT_DB
if not _is_writable(DB_PATH):
DB_PATH = DEFAULT_DB
# Resolve SCHEMA_PATH
_env_schema = os.getenv("SCHEMA_PATH")
SCHEMA_PATH = Path(_env_schema).resolve() if _env_schema else DEFAULT_SCHEMA
if not _is_writable(SCHEMA_PATH):
SCHEMA_PATH = DEFAULT_SCHEMA
# Ensure runtime schema exists in the chosen writable location
def _ensure_runtime_schema():
if SCHEMA_PATH.exists():
return
src = CANONICAL_SCHEMA if CANONICAL_SCHEMA.exists() else (REPO_DIR / "schema.sql")
if not src.exists():
raise FileNotFoundError(f"Canonical schema not found at {src}")
SCHEMA_PATH.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(src, SCHEMA_PATH)
def _log_paths():
print("[DB paths]")
print(f" REPO_DIR = {REPO_DIR}")
print(f" CANON_SCHEMA = {CANONICAL_SCHEMA} (exists={CANONICAL_SCHEMA.exists()})")
print(f" RUNTIME_SCHEMA= {SCHEMA_PATH} (exists={SCHEMA_PATH.exists()})")
print(f" DB_PATH = {DB_PATH} (exists={DB_PATH.exists()})")
# Call once on import
_ensure_runtime_schema()
_log_paths()
def get_connection() -> sqlite3.Connection:
conn = sqlite3.connect(str(DB_PATH), timeout=30, check_same_thread=False)
conn.row_factory = sqlite3.Row
with conn:
conn.execute("PRAGMA journal_mode=WAL;")
conn.execute("PRAGMA foreign_keys=ON;")
conn.execute("PRAGMA synchronous=NORMAL;")
return conn
def init_db(w3=None, confirmations: int = 12) -> None:
"""
Initialize or verify DB schema.
w3 + confirmations are accepted for compatibility with indexer,
but not used directly here. This way you won’t get argument errors.
"""
sql = SCHEMA_PATH.read_text(encoding="utf-8")
with get_connection() as conn:
conn.executescript(sql)
print(f"[DB] Schema verified. Using DB at {DB_PATH}")
def get_latest_netflow():
with get_connection() as conn:
cur = conn.cursor()
cur.execute("""
SELECT created_at, cumulative_value
FROM netflow
ORDER BY created_at DESC
LIMIT 1
""")
row = cur.fetchone()
if not row:
return None
return {"created_at": row["created_at"], "cumulative_value": str(row["cumulative_value"])}
def table_counts() -> dict:
out = {}
with get_connection() as conn:
c = conn.cursor()
for t in ("transfers", "netflow", "raw_logs", "meta"):
try:
c.execute(f"SELECT COUNT(*) AS n FROM {t}")
out[t] = int(c.fetchone()["n"])
except Exception:
out[t] = -1
return out
# do not refer
# import sqlite3
# from pathlib import Path
# DB_PATH = Path(__file__).resolve().parent.parent / "data" / "netflow.db"
# def get_connection():
# conn = sqlite3.connect(DB_PATH)
# conn.row_factory = sqlite3.Row # lets us fetch rows like dictionary
# return conn
# def init_db():
# conn = get_connection()
# cur = conn.cursor()
# # table for raw transactions we care about
# cur.execute("""
# CREATE TABLE IF NOT EXISTS transactions (
# tx_hash TEXT PRIMARY KEY,
# block_number INTEGER,
# from_address TEXT,
# to_address TEXT,
# value REAL,
# timestamp INTEGER
# );
# """)
# # table to track cumulative netflow / running netflow values
# cur.execute("""
# CREATE TABLE IF NOT EXISTS netflow (
# id INTEGER PRIMARY KEY AUTOINCREMENT,
# timestamp INTEGER,
# cumulative_value REAL
# );
# """)
# conn.commit()
# conn.close()
# print(f"Database initialized at {DB_PATH}")
|