CounterDroneBackend/src/CounterDrone.Core/DatabaseManager.cs
tian ca0ce8aa52 重命名核心模型:TargetConfig→DroneProfile, SimTask→Scenario, TaskFullConfig→ScenarioConfig, TaskId→ScenarioId
- DroneType 枚举清理:移除 Electric/Piston,重编号 HighSpeed=2
- planner_config.json / defaults.json 同步迁移
- 238 单元测试全部通过
2026-06-18 15:02:58 +08:00

129 lines
4.9 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using CounterDrone.Core.Models;
using CounterDrone.Core.Repository;
using CounterDrone.Core.Services;
using SQLite;
namespace CounterDrone.Core
{
/// <summary>数据库管理器 — 建表 / 连接管理</summary>
public class DatabaseManager
{
private readonly IPathProvider _paths;
public DatabaseManager(IPathProvider paths)
{
_paths = paths;
}
/// <summary>初始化主数据库(建表 + 种子数据)</summary>
public SQLiteConnection OpenMainDb()
{
var dbPath = _paths.GetMainDbPath();
var db = new SQLiteConnection(dbPath);
CreateMainTables(db);
SeedDefaultData(db);
SeedDefaultScenarios(db);
return db;
}
/// <summary>创建/打开任务帧数据库</summary>
public SQLiteConnection OpenFrameDb(string scenarioId)
{
var dbPath = Path.Combine(_paths.GetFramesDir(), $"{scenarioId}.db");
var db = new SQLiteConnection(dbPath);
db.CreateTable<SimFrameRecord>();
db.CreateIndex("SimFrameRecord", new[] { "ScenarioId", "FrameIndex" });
return db;
}
/// <summary>删除任务帧数据库文件</summary>
public void DeleteFrameDb(string scenarioId)
{
var dbPath = Path.Combine(_paths.GetFramesDir(), $"{scenarioId}.db");
if (File.Exists(dbPath))
File.Delete(dbPath);
}
private void SeedDefaultData(SQLiteConnection db)
{
db.CreateTable<MetaEntry>();
var defaults = DefaultData.Load(_paths);
var currentVersion = db.Table<MetaEntry>()
.FirstOrDefault(m => m.Key == "defaultsVersion")?.Value;
// 版本未变且数据已存在 → 跳过
if (currentVersion == defaults.Version && db.Table<AmmunitionSpec>().Count() > 0)
return;
// 插入或更新默认数据(按 Id 覆盖,不删除用户自建数据)
foreach (var a in defaults.Ammunition) db.InsertOrReplace(a);
foreach (var f in defaults.FireUnits) db.InsertOrReplace(f);
foreach (var d in defaults.Drones) db.InsertOrReplace(d);
foreach (var s in defaults.Sensors) db.InsertOrReplace(s);
foreach (var e in defaults.Environments) db.InsertOrReplace(e);
foreach (var f in defaults.Formations) db.InsertOrReplace(f);
foreach (var r in defaults.Routes)
{
r.WaypointsJson = System.Text.Json.JsonSerializer.Serialize(r.Waypoints);
db.InsertOrReplace(r);
}
db.InsertOrReplace(new MetaEntry { Key = "defaultsVersion", Value = defaults.Version });
}
private void SeedDefaultScenarios(SQLiteConnection db)
{
var currentVersion = db.Table<MetaEntry>()
.FirstOrDefault(m => m.Key == "scenariosVersion")?.Value;
// 版本未变 → 跳过
if (currentVersion == "3") return;
var defaults = DefaultData.Load(_paths);
var scenario = new ScenarioService(
new ScenarioRepository(db), new CombatSceneRepository(db),
new ControlZoneRepository(db), new DroneProfileRepository(db),
new EquipmentDeploymentRepository(db), new CloudDispersalRepository(db),
new RoutePlanRepository(db), new WaypointRepository(db));
DefaultScenarios.Seed(scenario, defaults);
db.InsertOrReplace(new MetaEntry { Key = "scenariosVersion", Value = "3" });
}
private void CreateMainTables(SQLiteConnection db)
{
db.CreateTable<ModelInfo>();
db.CreateTable<AmmunitionSpec>();
db.CreateTable<Scenario>();
db.CreateTable<CombatScene>();
db.CreateTable<ControlZone>();
db.CreateTable<DroneProfile>();
db.CreateTable<EquipmentDeployment>();
db.CreateTable<CloudDispersal>();
db.CreateTable<RoutePlan>();
db.CreateIndex("RoutePlan", new[] { "ScenarioId", "WaveId" }, true);
db.CreateTable<Waypoint>();
db.CreateTable<SimulationReport>();
db.CreateTable<FireUnitSpec>();
db.CreateTable<DroneSpec>();
db.CreateTable<SensorSpec>();
db.CreateTable<EnvironmentSpec>();
db.CreateTable<FormationTemplate>();
db.CreateTable<RouteTemplate>();
db.CreateIndex("Scenario", "TaskNumber");
db.CreateIndex("ControlZone", "ScenarioId");
db.CreateIndex("DroneProfile", "ScenarioId");
db.CreateIndex("EquipmentDeployment", "ScenarioId");
db.CreateIndex("Waypoint", "ScenarioId");
db.CreateIndex("SimulationReport", "ScenarioId");
}
}
}