SIT/database/repositories/field_repository.py

291 lines
8.2 KiB
Python
Raw Normal View History

2026-01-29 09:08:31 +00:00
"""
字段数据访问层
负责字段数据的CRUD操作
"""
from typing import List, Optional, Dict, Any
from datetime import datetime
from database import db_manager
from models.field import Field
from config import FieldType
from utils.logger import get_logger
logger = get_logger(__name__)
class FieldRepository:
"""字段数据访问类"""
def create(self, field_obj: Field) -> int:
"""
创建字段
Args:
field_obj: 字段对象
Returns:
新创建的字段ID
"""
sql = """
INSERT INTO fields (
full_name, domain, sub_domains, name, type,
range_min, range_max, default_value, unit, description
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"""
params = (
field_obj.full_name,
field_obj.domain,
field_obj.get_sub_domains_str(),
field_obj.name,
field_obj.type.value,
field_obj.range_min,
field_obj.range_max,
field_obj.default_value,
field_obj.unit,
field_obj.description,
)
try:
db_manager.execute_update(sql, params)
field_id = db_manager.get_last_insert_id()
logger.info(f"Created field: {field_obj.full_name} (ID: {field_id})")
return field_id
except Exception as e:
logger.error(f"Failed to create field: {e}")
raise
def get_by_id(self, field_id: int) -> Optional[Field]:
"""
根据ID获取字段
Args:
field_id: 字段ID
Returns:
字段对象或None
"""
sql = "SELECT * FROM fields WHERE id = ?"
try:
rows = db_manager.execute_query(sql, (field_id,))
if rows:
return self._row_to_field(rows[0])
return None
except Exception as e:
logger.error(f"Failed to get field by id {field_id}: {e}")
raise
def get_by_full_name(self, full_name: str) -> Optional[Field]:
"""
根据完整名称获取字段
Args:
full_name: 完整名称
Returns:
字段对象或None
"""
sql = "SELECT * FROM fields WHERE full_name = ?"
try:
rows = db_manager.execute_query(sql, (full_name,))
if rows:
return self._row_to_field(rows[0])
return None
except Exception as e:
logger.error(f"Failed to get field by full_name {full_name}: {e}")
raise
def update(self, field_obj: Field) -> bool:
"""
更新字段
Args:
field_obj: 字段对象
Returns:
是否更新成功
"""
sql = """
UPDATE fields SET
full_name = ?, domain = ?, sub_domains = ?, name = ?, type = ?,
range_min = ?, range_max = ?, default_value = ?, unit = ?, description = ?
WHERE id = ?
"""
params = (
field_obj.full_name,
field_obj.domain,
field_obj.get_sub_domains_str(),
field_obj.name,
field_obj.type.value,
field_obj.range_min,
field_obj.range_max,
field_obj.default_value,
field_obj.unit,
field_obj.description,
field_obj.id,
)
try:
rows_affected = db_manager.execute_update(sql, params)
if rows_affected > 0:
logger.info(f"Updated field: {field_obj.full_name} (ID: {field_obj.id})")
return True
return False
except Exception as e:
logger.error(f"Failed to update field: {e}")
raise
def delete(self, field_id: int) -> bool:
"""
删除字段
Args:
field_id: 字段ID
Returns:
是否删除成功
"""
sql = "DELETE FROM fields WHERE id = ?"
try:
rows_affected = db_manager.execute_update(sql, (field_id,))
if rows_affected > 0:
logger.info(f"Deleted field ID: {field_id}")
return True
return False
except Exception as e:
logger.error(f"Failed to delete field: {e}")
raise
def search(self, domain: Optional[str] = None, name: Optional[str] = None,
field_type: Optional[FieldType] = None, limit: int = 100,
offset: int = 0) -> List[Field]:
"""
搜索字段
Args:
domain: 域名支持模糊查询
name: 字段名支持模糊查询
field_type: 字段类型
limit: 返回数量限制
offset: 偏移量
Returns:
字段列表
"""
sql = "SELECT * FROM fields WHERE 1=1"
params = []
if domain:
sql += " AND domain LIKE ?"
params.append(f"%{domain}%")
if name:
sql += " AND name LIKE ?"
params.append(f"%{name}%")
if field_type:
sql += " AND type = ?"
params.append(field_type.value)
sql += " ORDER BY created_time DESC LIMIT ? OFFSET ?"
params.extend([limit, offset])
try:
rows = db_manager.execute_query(sql, tuple(params))
return [self._row_to_field(row) for row in rows]
except Exception as e:
logger.error(f"Failed to search fields: {e}")
raise
def get_all(self, limit: int = 1000, offset: int = 0) -> List[Field]:
"""
获取所有字段
Args:
limit: 返回数量限制
offset: 偏移量
Returns:
字段列表
"""
sql = "SELECT * FROM fields ORDER BY created_time DESC LIMIT ? OFFSET ?"
try:
rows = db_manager.execute_query(sql, (limit, offset))
return [self._row_to_field(row) for row in rows]
except Exception as e:
logger.error(f"Failed to get all fields: {e}")
raise
def count(self, domain: Optional[str] = None, name: Optional[str] = None,
field_type: Optional[FieldType] = None) -> int:
"""
统计字段数量
Args:
domain: 域名
name: 字段名
field_type: 字段类型
Returns:
字段数量
"""
sql = "SELECT COUNT(*) as count FROM fields WHERE 1=1"
params = []
if domain:
sql += " AND domain LIKE ?"
params.append(f"%{domain}%")
if name:
sql += " AND name LIKE ?"
params.append(f"%{name}%")
if field_type:
sql += " AND type = ?"
params.append(field_type.value)
try:
rows = db_manager.execute_query(sql, tuple(params) if params else None)
return rows[0]['count'] if rows else 0
except Exception as e:
logger.error(f"Failed to count fields: {e}")
raise
def get_domains(self) -> List[str]:
"""
获取所有域名
Returns:
域名列表
"""
sql = "SELECT DISTINCT domain FROM fields ORDER BY domain"
try:
rows = db_manager.execute_query(sql)
return [row['domain'] for row in rows]
except Exception as e:
logger.error(f"Failed to get domains: {e}")
raise
def _row_to_field(self, row) -> Field:
"""将数据库行转换为Field对象"""
return Field(
id=row['id'],
full_name=row['full_name'],
domain=row['domain'],
sub_domains=Field.parse_sub_domains(row['sub_domains']) if row['sub_domains'] else [],
name=row['name'],
type=FieldType(row['type']),
range_min=row['range_min'],
range_max=row['range_max'],
default_value=row['default_value'],
unit=row['unit'],
description=row['description'],
created_time=datetime.fromisoformat(row['created_time']) if row['created_time'] else None,
updated_time=datetime.fromisoformat(row['updated_time']) if row['updated_time'] else None,
)