Initial commit
This commit is contained in:
95
backend/app/repositories/mysql_repository.py
Normal file
95
backend/app/repositories/mysql_repository.py
Normal file
@ -0,0 +1,95 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pymysql
|
||||
|
||||
|
||||
class MySQLRepository:
|
||||
def __init__(self, config: dict[str, Any]) -> None:
|
||||
self.config = config
|
||||
self._ensure_schema()
|
||||
|
||||
def _connect(self):
|
||||
return pymysql.connect(
|
||||
host=self.config["mysql_host"],
|
||||
port=int(self.config.get("mysql_port", 3306)),
|
||||
user=self.config["mysql_username"],
|
||||
password=self.config["mysql_password"],
|
||||
database=self.config["mysql_database"],
|
||||
charset=self.config.get("mysql_charset", "utf8mb4"),
|
||||
autocommit=True,
|
||||
cursorclass=pymysql.cursors.DictCursor,
|
||||
)
|
||||
|
||||
def _ensure_schema(self) -> None:
|
||||
statements = [
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS app_documents (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
category VARCHAR(64) NOT NULL,
|
||||
doc_key VARCHAR(128) NOT NULL,
|
||||
sort_value VARCHAR(64) DEFAULT NULL,
|
||||
payload LONGTEXT NOT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
updated_at DATETIME NOT NULL,
|
||||
UNIQUE KEY uniq_category_key (category, doc_key),
|
||||
KEY idx_category_sort (category, sort_value)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||
"""
|
||||
]
|
||||
with self._connect() as connection:
|
||||
with connection.cursor() as cursor:
|
||||
for statement in statements:
|
||||
cursor.execute(statement)
|
||||
|
||||
def read_document(self, category: str, doc_key: str, default: dict[str, Any] | None = None) -> dict[str, Any]:
|
||||
sql = "SELECT payload FROM app_documents WHERE category=%s AND doc_key=%s LIMIT 1"
|
||||
with self._connect() as connection:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(sql, (category, doc_key))
|
||||
row = cursor.fetchone()
|
||||
if not row:
|
||||
return default or {}
|
||||
return json.loads(row["payload"])
|
||||
|
||||
def write_document(
|
||||
self,
|
||||
category: str,
|
||||
doc_key: str,
|
||||
payload: dict[str, Any],
|
||||
*,
|
||||
sort_value: str | None = None,
|
||||
) -> None:
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
sql = """
|
||||
INSERT INTO app_documents (category, doc_key, sort_value, payload, created_at, updated_at)
|
||||
VALUES (%s, %s, %s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
sort_value=VALUES(sort_value),
|
||||
payload=VALUES(payload),
|
||||
updated_at=VALUES(updated_at)
|
||||
"""
|
||||
serialized = json.dumps(payload, ensure_ascii=False)
|
||||
with self._connect() as connection:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(sql, (category, doc_key, sort_value, serialized, now, now))
|
||||
|
||||
def list_documents(
|
||||
self,
|
||||
category: str,
|
||||
*,
|
||||
limit: int | None = None,
|
||||
descending: bool = True,
|
||||
) -> list[dict[str, Any]]:
|
||||
direction = "DESC" if descending else "ASC"
|
||||
sql = f"SELECT payload FROM app_documents WHERE category=%s ORDER BY sort_value {direction}, updated_at {direction}"
|
||||
params: list[Any] = [category]
|
||||
if limit is not None:
|
||||
sql += " LIMIT %s"
|
||||
params.append(limit)
|
||||
with self._connect() as connection:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(sql, params)
|
||||
rows = cursor.fetchall()
|
||||
return [json.loads(row["payload"]) for row in rows]
|
||||
Reference in New Issue
Block a user