From 9cbc499b48ddb2b49dc4a99273e4a321ee82787f Mon Sep 17 00:00:00 2001 From: gil zhang Date: Mon, 28 Oct 2024 00:02:04 +0800 Subject: [PATCH] add data storage --- ElectronBot.Braincase.sln | 19 ++++++++ .../Contracts/Services/ILingxiSpaceService.cs | 12 +++++ .../Lingxi/Filters/LingxiSpaceFilter.cs | 9 ++++ .../Models/Lingxi/LingxiSpace.cs | 36 ++++++++++++++ .../ElectronBot.Braincase.csproj | 1 + .../BraincaseDatabaseSettings.cs | 12 +++++ .../BraincaseLiteDBContext.cs | 48 +++++++++++++++++++ .../Collections/LingxiSpaceDocument.cs | 35 ++++++++++++++ .../LiteDBBase.cs | 31 ++++++++++++ .../Services/LiteDBLingxiSpaceService.cs | 18 +++++++ .../Services/LiteDBLocalSettingsService.cs | 13 +++++ .../Verdure.Braincase.DataStorage.csproj | 16 +++++++ 12 files changed, 250 insertions(+) create mode 100644 src/ElectronBot.Braincase.Core/Contracts/Services/ILingxiSpaceService.cs create mode 100644 src/ElectronBot.Braincase.Core/Models/Lingxi/Filters/LingxiSpaceFilter.cs create mode 100644 src/ElectronBot.Braincase.Core/Models/Lingxi/LingxiSpace.cs create mode 100644 src/Verdure.Braincase.DataStorage/BraincaseDatabaseSettings.cs create mode 100644 src/Verdure.Braincase.DataStorage/BraincaseLiteDBContext.cs create mode 100644 src/Verdure.Braincase.DataStorage/Collections/LingxiSpaceDocument.cs create mode 100644 src/Verdure.Braincase.DataStorage/LiteDBBase.cs create mode 100644 src/Verdure.Braincase.DataStorage/Services/LiteDBLingxiSpaceService.cs create mode 100644 src/Verdure.Braincase.DataStorage/Services/LiteDBLocalSettingsService.cs create mode 100644 src/Verdure.Braincase.DataStorage/Verdure.Braincase.DataStorage.csproj diff --git a/ElectronBot.Braincase.sln b/ElectronBot.Braincase.sln index 784a626..a06c23f 100644 --- a/ElectronBot.Braincase.sln +++ b/ElectronBot.Braincase.sln @@ -41,6 +41,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Verdure.Plugin.Copilot", "s EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{8EF77FC4-6C54-4F46-8957-E23E5E58E847}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Verdure.Braincase.DataStorage", "src\Verdure.Braincase.DataStorage\Verdure.Braincase.DataStorage.csproj", "{3ADA05B0-2834-475A-8635-9686EB158353}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -301,6 +303,22 @@ Global {0958CE17-DFF9-4AF8-8B25-8D9B9708BA8F}.Release|x64.Build.0 = Release|Any CPU {0958CE17-DFF9-4AF8-8B25-8D9B9708BA8F}.Release|x86.ActiveCfg = Release|Any CPU {0958CE17-DFF9-4AF8-8B25-8D9B9708BA8F}.Release|x86.Build.0 = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|arm64.ActiveCfg = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|arm64.Build.0 = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|x64.ActiveCfg = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|x64.Build.0 = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|x86.ActiveCfg = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Debug|x86.Build.0 = Debug|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|Any CPU.Build.0 = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|arm64.ActiveCfg = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|arm64.Build.0 = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|x64.ActiveCfg = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|x64.Build.0 = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|x86.ActiveCfg = Release|Any CPU + {3ADA05B0-2834-475A-8635-9686EB158353}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -321,6 +339,7 @@ Global {4A9E0A47-6386-45F2-84FF-3ACEC37B6A8E} = {B93FAB57-EB95-4516-9132-A584BA674458} {6085A146-AAB7-4CC5-8A5D-17A9FD1D495B} = {8EF77FC4-6C54-4F46-8957-E23E5E58E847} {0958CE17-DFF9-4AF8-8B25-8D9B9708BA8F} = {239CCEB2-7AA4-4250-BDE5-2120D3832DBF} + {3ADA05B0-2834-475A-8635-9686EB158353} = {8EF77FC4-6C54-4F46-8957-E23E5E58E847} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0EBF82F3-30A6-4BCC-950A-360C126FC118} diff --git a/src/ElectronBot.Braincase.Core/Contracts/Services/ILingxiSpaceService.cs b/src/ElectronBot.Braincase.Core/Contracts/Services/ILingxiSpaceService.cs new file mode 100644 index 0000000..3b76b5b --- /dev/null +++ b/src/ElectronBot.Braincase.Core/Contracts/Services/ILingxiSpaceService.cs @@ -0,0 +1,12 @@ +using Verdure.Braincase.Core.Models.Lingxi; +using Verdure.Braincase.Core.Models.Lingxi.Filters; + +namespace Verdure.Braincase.Core.Contracts.Services; +public interface ILingxiSpaceService +{ + Task AddAsync(LingxiSpace space); + Task RemoveAsync(string id); + Task UpdateAsync(LingxiSpace space); + Task GetAsync(string id); + Task> GetAllAsync(LingxiSpaceFilter filter); +} diff --git a/src/ElectronBot.Braincase.Core/Models/Lingxi/Filters/LingxiSpaceFilter.cs b/src/ElectronBot.Braincase.Core/Models/Lingxi/Filters/LingxiSpaceFilter.cs new file mode 100644 index 0000000..d605206 --- /dev/null +++ b/src/ElectronBot.Braincase.Core/Models/Lingxi/Filters/LingxiSpaceFilter.cs @@ -0,0 +1,9 @@ +namespace Verdure.Braincase.Core.Models.Lingxi.Filters; + +public class LingxiSpaceFilter +{ + public string ConversationId + { + get; set; + } +} diff --git a/src/ElectronBot.Braincase.Core/Models/Lingxi/LingxiSpace.cs b/src/ElectronBot.Braincase.Core/Models/Lingxi/LingxiSpace.cs new file mode 100644 index 0000000..0269f85 --- /dev/null +++ b/src/ElectronBot.Braincase.Core/Models/Lingxi/LingxiSpace.cs @@ -0,0 +1,36 @@ +using System.Text.Json; + +namespace Verdure.Braincase.Core.Models.Lingxi; +public class LingxiSpace +{ + public string Id + { + get; set; + } + public string Name + { + get; set; + } + public string Desc + { + get; set; + } + public string Type + { + get; set; + } + public JsonDocument Content + { + get; set; + } + + public DateTime CreatedTime + { + get; set; + } + + public string ConversationId + { + get; set; + } +} diff --git a/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj b/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj index 55adaeb..c9921ca 100644 --- a/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj +++ b/src/ElectronBot.Braincase/ElectronBot.Braincase.csproj @@ -282,6 +282,7 @@ + diff --git a/src/Verdure.Braincase.DataStorage/BraincaseDatabaseSettings.cs b/src/Verdure.Braincase.DataStorage/BraincaseDatabaseSettings.cs new file mode 100644 index 0000000..4788bbf --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/BraincaseDatabaseSettings.cs @@ -0,0 +1,12 @@ +namespace Verdure.Braincase.DataStorage; +public class BraincaseDatabaseSettings +{ + public string BraincaseLiteDB + { + get; set; + } = string.Empty; + public string TablePrefix + { + get; set; + } = string.Empty; +} diff --git a/src/Verdure.Braincase.DataStorage/BraincaseLiteDBContext.cs b/src/Verdure.Braincase.DataStorage/BraincaseLiteDBContext.cs new file mode 100644 index 0000000..f884e44 --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/BraincaseLiteDBContext.cs @@ -0,0 +1,48 @@ +using System.Globalization; +using LiteDB; +using Verdure.Braincase.DataStorage.Collections; + +namespace Verdure.Braincase.DataStorage; + +public class BraincaseLiteDBContext : IDisposable +{ + private readonly LiteDatabase _liteDBClient; + private readonly string _collectionPrefix; + + private const string DB_NAME_INDEX = "authSource"; + + public BraincaseLiteDBContext(BraincaseDatabaseSettings dbSettings) + { + var mapper = new BsonMapper(); + mapper.RegisterType( + value => value.ToString("o", CultureInfo.InvariantCulture), + bson => DateTime.ParseExact + (bson, "o", CultureInfo.InvariantCulture, + DateTimeStyles.RoundtripKind)); + + mapper.RegisterType( + value => value.ToString("o", CultureInfo.InvariantCulture), + bson => DateTimeOffset.ParseExact + (bson, "o", CultureInfo.InvariantCulture, + DateTimeStyles.RoundtripKind)); + + var dbConnectionString = dbSettings.BraincaseLiteDB; + var connectionString = new ConnectionString(dbConnectionString) + { + Connection = ConnectionType.Shared + }; + _liteDBClient = new LiteDatabase(connectionString, mapper); + + _collectionPrefix = dbSettings.TablePrefix ?? "Braincase"; + } + + private LiteDatabase Database => _liteDBClient; + + public void Dispose() + { + _liteDBClient?.Dispose(); + } + + public ILiteCollection LingxiSpaces + => Database.GetCollection($"{_collectionPrefix}_LingxiSpaces"); +} diff --git a/src/Verdure.Braincase.DataStorage/Collections/LingxiSpaceDocument.cs b/src/Verdure.Braincase.DataStorage/Collections/LingxiSpaceDocument.cs new file mode 100644 index 0000000..a0bf8a5 --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/Collections/LingxiSpaceDocument.cs @@ -0,0 +1,35 @@ +using System.Text.Json; + +namespace Verdure.Braincase.DataStorage.Collections; +public class LingxiSpaceDocument : LiteDBBase +{ + public string Name + { + get; set; + } = string.Empty; + + public string Desc + { + get; set; + } = string.Empty; + + public string Type + { + get; set; + } = string.Empty; + + public JsonDocument? Content + { + get; set; + } + + public DateTime CreatedTime + { + get; set; + } + + public string ConversationId + { + get; set; + } = string.Empty; +} diff --git a/src/Verdure.Braincase.DataStorage/LiteDBBase.cs b/src/Verdure.Braincase.DataStorage/LiteDBBase.cs new file mode 100644 index 0000000..74c99e0 --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/LiteDBBase.cs @@ -0,0 +1,31 @@ +using LiteDB; + +namespace Verdure.Braincase.DataStorage; + +public abstract class LiteDBBase +{ + private string? id; + + public string Id + { + get + { + if (string.IsNullOrEmpty(id)) + { + id = GenerateId(); + } + return id; + } + set => id = value; + } + + private string GenerateId() + { + // Generate and return the id here + // You can use any logic to generate the id + // For example, you can use Guid.NewGuid().ToString() to generate a unique id + return Guid.NewGuid().ToString(); + } +} + + diff --git a/src/Verdure.Braincase.DataStorage/Services/LiteDBLingxiSpaceService.cs b/src/Verdure.Braincase.DataStorage/Services/LiteDBLingxiSpaceService.cs new file mode 100644 index 0000000..5811b9e --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/Services/LiteDBLingxiSpaceService.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verdure.Braincase.Core.Contracts.Services; +using Verdure.Braincase.Core.Models.Lingxi; +using Verdure.Braincase.Core.Models.Lingxi.Filters; + +namespace Verdure.Braincase.DataStorage.Services; +public class LiteDBLingxiSpaceService : ILingxiSpaceService +{ + public Task AddAsync(LingxiSpace space) => throw new NotImplementedException(); + public Task> GetAllAsync(LingxiSpaceFilter filter) => throw new NotImplementedException(); + public Task GetAsync(string id) => throw new NotImplementedException(); + public Task RemoveAsync(string id) => throw new NotImplementedException(); + public Task UpdateAsync(LingxiSpace space) => throw new NotImplementedException(); +} diff --git a/src/Verdure.Braincase.DataStorage/Services/LiteDBLocalSettingsService.cs b/src/Verdure.Braincase.DataStorage/Services/LiteDBLocalSettingsService.cs new file mode 100644 index 0000000..1735f68 --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/Services/LiteDBLocalSettingsService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ElectronBot.Braincase.Contracts.Services; + +namespace Verdure.Braincase.DataStorage.Services; +public class LiteDBLocalSettingsService : ILocalSettingsService +{ + public Task ReadSettingAsync(string key) => throw new NotImplementedException(); + public Task SaveSettingAsync(string key, T value) => throw new NotImplementedException(); +} diff --git a/src/Verdure.Braincase.DataStorage/Verdure.Braincase.DataStorage.csproj b/src/Verdure.Braincase.DataStorage/Verdure.Braincase.DataStorage.csproj new file mode 100644 index 0000000..209a9a7 --- /dev/null +++ b/src/Verdure.Braincase.DataStorage/Verdure.Braincase.DataStorage.csproj @@ -0,0 +1,16 @@ + + + + net8.0 + enable + enable + + + + + + + + + +