brisonus_app_eq/database/db_manager.py

166 lines
6.1 KiB
Python
Raw Normal View History

2025-02-15 21:20:54 +08:00
import sqlite3
from typing import List, Optional, Tuple
from pathlib import Path
import os
from .models import FilterData, ParamData, ConfigData
class DatabaseManager:
_instance = None
def __new__(cls, db_path: str = None):
if cls._instance is None:
cls._instance = super(DatabaseManager, cls).__new__(cls)
if db_path is None:
app_dir = Path(os.path.dirname(os.path.abspath(__file__))).parent
data_dir = app_dir / 'data'
db_path = str(data_dir / 'database.db')
cls._instance.db_path = db_path
cls._instance._init_database()
return cls._instance
def __init__(self):
self.init_database()
def _init_database(self):
Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)
with sqlite3.connect(self.db_path) as conn:
conn.executescript("""
CREATE TABLE IF NOT EXISTS configs (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS params (
id INTEGER PRIMARY KEY,
config_id INTEGER,
delay_data1 FLOAT,
ENC_volume_data1 FLOAT,
ENT_mx_right_data FLOAT,
ENT_mix_left_data FLOAT,
FOREIGN KEY (config_id) REFERENCES configs(id)
);
CREATE TABLE IF NOT EXISTS filters (
id INTEGER PRIMARY KEY,
config_id INTEGER,
filter_type TEXT NOT NULL,
freq FLOAT,
q FLOAT,
gain FLOAT,
slope FLOAT,
enabled BOOLEAN DEFAULT TRUE,
position INTEGER,
FOREIGN KEY (config_id) REFERENCES configs(id)
);
""")
def get_connection(self):
return sqlite3.connect(self.db_path)
def get_all_configs(self) -> List[ConfigData]:
with self.get_connection() as conn:
cursor = conn.execute("SELECT id, name, created_at FROM configs")
return [ConfigData(*row) for row in cursor.fetchall()]
def load_config(self, config_id: int) -> Tuple[Optional[ParamData], List[FilterData]]:
with self.get_connection() as conn:
cursor = conn.execute(
"SELECT * FROM params WHERE config_id = ?",
(config_id,)
)
param_row = cursor.fetchone()
params = ParamData(*param_row[2:]) if param_row else None
cursor = conn.execute(
"SELECT * FROM filters WHERE config_id = ? ORDER BY position",
(config_id,)
)
filters = [FilterData(*row[2:]) for row in cursor.fetchall()]
return params, filters
def save_config(self, name: str, params: ParamData, filters: List[FilterData]) -> int:
with self.get_connection() as conn:
cursor = conn.execute(
"INSERT INTO configs (name) VALUES (?)",
(name,)
)
config_id = cursor.lastrowid
conn.execute(
"""INSERT INTO params
(config_id, delay_data1, ENC_volume_data1, ENT_mx_right_data, ENT_mix_left_data)
VALUES (?, ?, ?, ?, ?)""",
(config_id, params.delay_data1, params.ENC_volume_data1,
params.ENT_mx_right_data, params.ENT_mix_left_data)
)
for filter_data in filters:
conn.execute(
"""INSERT INTO filters
(config_id, filter_type, freq, q, gain, slope, enabled, position)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(config_id, filter_data.filter_type, filter_data.freq,
filter_data.q, filter_data.gain, filter_data.slope,
filter_data.enabled, filter_data.position)
)
conn.commit()
return config_id
def update_filter(self, filter_id: int, **kwargs):
with self.get_connection() as conn:
set_clause = ", ".join(f"{k} = ?" for k in kwargs.keys())
query = f"UPDATE filters SET {set_clause} WHERE id = ?"
conn.execute(query, (*kwargs.values(), filter_id))
conn.commit()
def update_params(self, config_id: int, params: ParamData):
with self.get_connection() as conn:
conn.execute(
"""UPDATE params SET
delay_data1 = ?, ENC_volume_data1 = ?,
ENT_mx_right_data = ?, ENT_mix_left_data = ?
WHERE config_id = ?""",
(params.delay_data1, params.ENC_volume_data1,
params.ENT_mx_right_data, params.ENT_mix_left_data,
config_id)
)
conn.commit()
def init_database(self):
"""初始化数据库,如果没有数据则创建默认配置"""
configs = self.get_all_configs()
if not configs:
# 创建默认配置
default_params = ParamData(
delay_data1=0.0,
ENC_volume_data1=0.0,
ENT_mx_right_data=0.0,
ENT_mix_left_data=0.0
)
# 创建一些默认滤波器
default_filters = [
FilterData(
filter_type="PEQ",
freq=1000.0,
q=1.0,
gain=0.0,
slope=12.0
),
FilterData(
filter_type="HPF",
freq=20.0,
q=0.707,
gain=0.0,
slope=12.0
)
]
# 保存默认配置
self.save_config("Default Config", default_params, default_filters)