WIP: database class.

- 修正disk拼写
- 为测试项目添加dylib引用
- 修复无法打开数据库的问题
- 为Deepseek TUI更新Agents.md
This commit is contained in:
2026-05-22 14:16:33 +08:00
parent 5a97159324
commit e33de83c75
9 changed files with 48 additions and 18 deletions
+21
View File
@@ -37,3 +37,24 @@ dotnet test --filter "FullyQualifiedName~ClassName.MethodName" # Run single tes
- Code and comments are in **Chinese**.
- Namespace: `OCES.Resonance.Core` (Core), `OCES.Resonance.AtlFieldExtractor` (extractor), `OCES.Resonance.Core.Tests` (tests).
- Git commit style: `WIP: <description>` (no conventional commits).
## AI 助手工具说明(DeepSeek TUI
当前工作环境为 DeepSeek TUI,文件操作工具采用**延迟加载**机制,不在初始工具列表中。首次调用会触发加载并返回 schema 提示(不执行),用正确参数重试后正常执行。
### 可用文件操作工具
| 工具 | 用途 | 参数注意事项 |
|------|------|-------------|
| `write_file` | 创建/覆盖文件 | `path` + `content` |
| `edit_file` | 单次查找替换 | `path` + `search` + `replace`(注意不是 `old_string`/`new_string` |
| `apply_patch` | 结构化 patch(多块变更) | `path` + `patch`unified diff 格式) |
| `read_file` | 读取文件 | `path`,支持 `start_line`/`max_lines` 分页;PDF 自动提取 |
| `list_dir` | 列出目录 | `path`(可选) |
| `grep_files` | 正则搜索文件内容 | `pattern`,支持 `include`/`exclude` glob、`context_lines` |
### 使用模式
- 写入/编辑/打补丁:需**两次调用**(首次触发加载,第二次执行)
- 读取/搜索:直接可用,单次调用
+3 -3
View File
@@ -162,9 +162,9 @@ public class AudioMetadataReaderTest
if (int.TryParse(metaFields["TrackNumber"], out int trackNum) && trackNum > 0)
Assert.Equal(trackNum, meta.TrackNumber);
// DiscNumber
if (int.TryParse(metaFields["DiscNumber"], out int discNum) && discNum > 0)
Assert.Equal(discNum, meta.DiscNumber);
// DiskNumber
if (int.TryParse(metaFields["DiskNumber"], out int discNum) && discNum > 0)
Assert.Equal(discNum, meta.DiskNumber);
// Year
if (int.TryParse(metaFields["Year"], out int year) && year > 0)
+1
View File
@@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.10" />
<PackageReference Include="FluentAssertions" Version="8.9.0" />
<PackageReference Include="JetBrains.Annotations" Version="2025.2.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
+2 -2
View File
@@ -12,7 +12,7 @@ public class DatabaseTests
public void InitializeDatabase_ShouldCreateAudioFilesTable()
{
string dbName = NewDbName();
string dbPath = $"{dbName}.rdb";
string dbPath = $"{Path.Combine(PreferencesManager.GetDefaultDatabasePath(), dbName)}.rdb";
try
{
@@ -60,7 +60,7 @@ public class DatabaseTests
public void InitializeDatabase_ShouldBeIdempotent()
{
string dbName = NewDbName();
string dbPath = $"{dbName}.rdb";
string dbPath = $"{Path.Combine(PreferencesManager.GetDefaultDatabasePath(), dbName)}.rdb";
try
{
+1 -1
View File
@@ -139,7 +139,7 @@ public class AudioFileMeta
/// <summary>CD标题,原始CD专辑名称</summary>
public string? CdTitle { get; set; }
public int? DiscNumber { get; set; }
public int? DiskNumber { get; set; }
/// <summary>曲目标题,音乐或音轨的标题</summary>
public string? TrackTitle { get; set; }
+1 -1
View File
@@ -54,7 +54,7 @@ public class AudioMetadataReader
Composer = track.Composer,
Copyright = track.Copyright,
Description = track.Comment,
DiscNumber = track.DiscNumber,
DiskNumber = track.DiscNumber,
FxName = GetField(track, "ixml.USER.FXNAME"),
Genre = track.Genre,
Group = track.Group,
+5 -5
View File
@@ -22,7 +22,7 @@ public static class Database
/// </summary>
public static void InitializeDatabase(string databaseName = "default")
{
using var connection = GetConnection();
using var connection = GetConnection(databaseName);
connection.Open();
const string sql = """
@@ -143,7 +143,7 @@ public static class Database
release_date, track_year, is_edited, is_split, location, [group],
markers, comments, notes, copyright, coding_history, microphone,
mic_perspective,
fx_name, channel_layout, bwf_umid, disc_number, track_number, artwork, waveform,
fx_name, channel_layout, bwf_umid, disk_number, track_number, artwork, waveform,
user1, user2, user3, user4, user5, user6, user7, user8
) VALUES (
@UniqueId, @ShortId, @Md5, @Path, @Filename, @Folder, @Directory,
@@ -157,7 +157,7 @@ public static class Database
@ReleaseDate, @TrackYear, @IsEdited, @IsSplit, @Location, @Group,
@Markers, @Comments, @Notes, @Copyright, @BwfCodingHistory, @Microphone,
@MicPerspective,
@FxName, @ChannelLayout, @BwfUmid, @DiscNumber, @TrackNumber, @Artwork, @Waveform,
@FxName, @ChannelLayout, @BwfUmid, @DiskNumber, @TrackNumber, @Artwork, @Waveform,
@User1, @User2, @User3, @User4, @User5, @User6, @User7, @User8
);
";
@@ -198,7 +198,7 @@ public static class Database
release_date, track_year, is_edited, is_split, location, [group],
markers, comments, notes, copyright, coding_history, microphone,
mic_perspective,
fx_name, channel_layout, bwf_umid, disc_number, track_number, artwork, waveform,
fx_name, channel_layout, bwf_umid, disk_number, track_number, artwork, waveform,
user1, user2, user3, user4, user5, user6, user7, user8
) VALUES (
@UniqueId, @ShortId, @Md5, @Path, @Filename, @Folder, @Directory,
@@ -212,7 +212,7 @@ public static class Database
@ReleaseDate, @TrackYear, @IsEdited, @IsSplit, @Location, @Group,
@Markers, @Comments, @Notes, @Copyright, @BwfCodingHistory, @Microphone,
@MicPerspective,
@FxName, @ChannelLayout, @BwfUmid, @DiscNumber, @TrackNumber, @Artwork, @Waveform,
@FxName, @ChannelLayout, @BwfUmid, @DiskNumber, @TrackNumber, @Artwork, @Waveform,
@User1, @User2, @User3, @User4, @User5, @User6, @User7, @User8
);
";
+12 -6
View File
@@ -51,14 +51,18 @@ public static class PreferencesManager
{
if (OperatingSystem.IsMacOS())
{
string library = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(library, "OCES", "Resonance", "Databases");
string applicationSupport = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
DirectoryInfo databasePath = new(Path.Combine(applicationSupport, "OCES", "Resonance", "Databases"));
if (!databasePath.Exists) Directory.CreateDirectory(databasePath.FullName);
return databasePath.FullName;
}
if (OperatingSystem.IsWindows())
{
string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(localAppData, "OCES", "Resonance", "Databases");
DirectoryInfo databasePath = new(Path.Combine(localAppData, "OCES", "Resonance", "Databases"));
if (!databasePath.Exists) Directory.CreateDirectory(databasePath.FullName);
return databasePath.FullName;
}
if (OperatingSystem.IsLinux())
@@ -66,7 +70,9 @@ public static class PreferencesManager
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME")
?? Path.Combine(home, ".local", "share");
return Path.Combine(xdgDataHome, "Resonance", "Databases");
DirectoryInfo databasePath = new(Path.Combine(xdgDataHome, "Resonance", "Databases"));
if (!databasePath.Exists) Directory.CreateDirectory(databasePath.FullName);
return databasePath.FullName;
}
return string.Empty;
@@ -79,8 +85,8 @@ public static class PreferencesManager
{
if (OperatingSystem.IsMacOS())
{
string library = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(library, "Preferences", "com.oces.Resonance.json");
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
return Path.Combine(home, "Library", "Preferences", "com.oces.Resonance.json");
}
if (OperatingSystem.IsWindows())
+2
View File
@@ -2,6 +2,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFormat_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2026_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fe2d95a1d7b987bbb7785b2ad7e2e3e29075ba79cdf7619dd26c10d266c5_003FFormat_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOSPlatform_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2026_002E1_003Fresharper_002Dhost_003FSourcesCache_003F9e988c941e6515999ebab7336243c87df16e340b8faeb57b5f562d2b8a7c2c_003FOSPlatform_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATrack_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2026_002E1_003Fresharper_002Dhost_003FSourcesCache_003F872a20b9878a835418db772627eab53c29e04a65284443b02d35345255649a3a_003FTrack_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;
&lt;Assembly Path="/Users/oliver/.nuget/packages/fluentassertions/8.9.0/lib/net6.0/FluentAssertions.dll" /&gt;
&lt;Assembly Path="/Users/oliver/.nuget/packages/dapper/2.1.72/lib/net10.0/Dapper.dll" /&gt;
@@ -16,5 +17,6 @@
&lt;TestId&gt;xUnit::24F92458-FB39-44BE-A32F-41275183AF1B::net10.0::Core.Tests.AudioMetadataReaderTest.ReadMetadata_ShouldThrow_FileNotFoundException&lt;/TestId&gt;
&lt;TestId&gt;xUnit::24F92458-FB39-44BE-A32F-41275183AF1B::net10.0::Core.Tests.AudioMetadataReaderTest&lt;/TestId&gt;
&lt;TestId&gt;xUnit::24F92458-FB39-44BE-A32F-41275183AF1B::net10.0::Core.Tests.DatabaseTests.InitializeDatabase_ShouldCreateAudioFilesTable&lt;/TestId&gt;
&lt;TestId&gt;xUnit::24F92458-FB39-44BE-A32F-41275183AF1B::net10.0::Core.Tests.DatabaseTests.InitializeDatabase_ShouldBeIdempotent&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>