From a2a375935396ebaf53dee84f3c33211753646bdd Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Fri, 25 Aug 2023 23:41:01 -0500 Subject: [PATCH] add mongo repository --- .../Repositories}/IBotSharpRepository.cs | 5 +- .../Repositories/IBotSharpTable.cs | 5 + .../Repositories/MyDatabaseSettings.cs | 31 +++ .../Repositories/Records}/AgentRecord.cs | 17 +- .../Records}/ConversationRecord.cs | 7 +- .../Repositories/Records/RecordBase.cs | 11 + .../Repositories/Records}/UserAgentRecord.cs | 7 +- .../Repositories/Records}/UserRecord.cs | 7 +- .../Services/AgentService.CreateAgent.cs | 6 +- .../Agents/Services/AgentService.GetAgents.cs | 1 + .../Services/AgentService.UpdateAgent.cs | 3 +- .../Agents/Services/AgentService.cs | 1 + .../BotSharp.Core/BotSharp.Core.csproj | 4 + .../BotSharpServiceCollectionExtensions.cs | 2 + .../Services/ConversationService.cs | 2 + .../Services/ConversationStateService.cs | 1 + .../Services/ConversationStorage.cs | 1 + .../BotSharp.Core/Functions/RouteToAgentFn.cs | 1 + .../Repository/Abstraction/IBotSharpTable.cs | 5 - .../Repository/BotSharpDbContext.cs | 2 + .../Collections/ConversationCollection.cs | 22 -- .../Repository/DataContextHelper.cs | 12 +- .../Repository/FileRepository.cs | 2 + .../Repository/IMongoDbCollection.cs | 8 - .../Repository/MongoDbContext.cs | 10 - .../Repository/MyDatabaseSettings.cs | 9 - .../Users/Services/UserService.cs | 4 +- src/Infrastructure/BotSharp.Core/Using.cs | 2 - .../BotSharp.Plugin.MongoRepository.csproj | 18 ++ .../Collections/AgentCollection.cs | 14 + .../Collections/ConversationCollection.cs | 13 + .../Collections/UserAgentCollection.cs | 11 + .../Collections/UserCollection.cs | 15 + .../MongoBase.cs | 11 + .../MongoDbContext.cs | 39 +++ .../MongoRepositoryPlugin.cs | 16 ++ .../Repository/MongoRepository.cs | 256 ++++++++++++++++++ .../BotSharp.Plugin.MongoRepository/Using.cs | 14 + 38 files changed, 498 insertions(+), 97 deletions(-) rename src/Infrastructure/{BotSharp.Core/Repository => BotSharp.Abstraction/Repositories}/IBotSharpRepository.cs (74%) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpTable.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Repositories/MyDatabaseSettings.cs rename src/Infrastructure/{BotSharp.Core/Repository/DbTables => BotSharp.Abstraction/Repositories/Records}/AgentRecord.cs (56%) rename src/Infrastructure/{BotSharp.Core/Repository/DbTables => BotSharp.Abstraction/Repositories/Records}/ConversationRecord.cs (83%) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Repositories/Records/RecordBase.cs rename src/Infrastructure/{BotSharp.Core/Repository/DbTables => BotSharp.Abstraction/Repositories/Records}/UserAgentRecord.cs (79%) rename src/Infrastructure/{BotSharp.Core/Repository/DbTables => BotSharp.Abstraction/Repositories/Records}/UserRecord.cs (86%) delete mode 100644 src/Infrastructure/BotSharp.Core/Repository/Abstraction/IBotSharpTable.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/BotSharp.Plugin.MongoRepository.csproj create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/Collections/AgentCollection.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/Collections/ConversationCollection.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserAgentCollection.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserCollection.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/MongoBase.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/MongoDbContext.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/MongoRepositoryPlugin.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/Repository/MongoRepository.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoRepository/Using.cs diff --git a/src/Infrastructure/BotSharp.Core/Repository/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs similarity index 74% rename from src/Infrastructure/BotSharp.Core/Repository/IBotSharpRepository.cs rename to src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 9490ee73..8c3dc959 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -1,4 +1,7 @@ -namespace BotSharp.Core.Repository; +using BotSharp.Abstraction.Repositories.Records; +using System.Linq; + +namespace BotSharp.Abstraction.Repositories; public interface IBotSharpRepository { diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpTable.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpTable.cs new file mode 100644 index 00000000..cc2e5633 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpTable.cs @@ -0,0 +1,5 @@ +namespace BotSharp.Abstraction.Repositories; + +public interface IBotSharpTable +{ +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/MyDatabaseSettings.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/MyDatabaseSettings.cs new file mode 100644 index 00000000..afa3a6c6 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/MyDatabaseSettings.cs @@ -0,0 +1,31 @@ +namespace BotSharp.Abstraction.Repositories; + +public class MyDatabaseSettings : DatabaseSettings +{ + public string[] Assemblies { get; set; } + public string FileRepository { get; set; } + public string MongoDb { get; set; } + public DbConnectionSetting BotSharp { get; set; } +} + +public class DatabaseSettings +{ + public string Default { get; set; } + public DbConnectionSetting DefaultConnection { get; set; } + public bool EnableSqlLog { get; set; } + public bool EnableSensitiveDataLogging { get; set; } + public bool EnableRetryOnFailure { get; set; } + public bool UseCamelCase { get; set; } +} + +public class DbConnectionSetting +{ + public string Master { get; set; } + + public string[] Slavers { get; set; } + + public DbConnectionSetting() + { + Slavers = new string[0]; + } +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/AgentRecord.cs similarity index 56% rename from src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs rename to src/Infrastructure/BotSharp.Abstraction/Repositories/Records/AgentRecord.cs index 31754c8e..d473a206 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/AgentRecord.cs @@ -1,11 +1,6 @@ -using BotSharp.Abstraction.Agents.Models; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; +namespace BotSharp.Abstraction.Repositories.Records; -namespace BotSharp.Core.Repository.DbTables; - -[Table("Agent")] -public class AgentRecord : DbRecord, IBotSharpTable +public class AgentRecord : RecordBase { [Required] [MaxLength(64)] @@ -15,10 +10,10 @@ public class AgentRecord : DbRecord, IBotSharpTable public string? Description { get; set; } [Required] - public DateTime CreatedDateTime { get; set; } + public DateTime CreatedTime { get; set; } [Required] - public DateTime UpdatedDateTime { get; set; } + public DateTime UpdatedTime { get; set; } public static AgentRecord FromAgent(Agent agent) { @@ -37,8 +32,8 @@ public class AgentRecord : DbRecord, IBotSharpTable Id = Id, Name = Name, Description = Description, - CreatedDateTime = CreatedDateTime, - UpdatedDateTime = UpdatedDateTime + CreatedDateTime = CreatedTime, + UpdatedDateTime = UpdatedTime }; } } diff --git a/src/Infrastructure/BotSharp.Core/Repository/DbTables/ConversationRecord.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/ConversationRecord.cs similarity index 83% rename from src/Infrastructure/BotSharp.Core/Repository/DbTables/ConversationRecord.cs rename to src/Infrastructure/BotSharp.Abstraction/Repositories/Records/ConversationRecord.cs index 167f664d..6a4dc338 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DbTables/ConversationRecord.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/ConversationRecord.cs @@ -1,11 +1,8 @@ using BotSharp.Abstraction.Conversations.Models; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -namespace BotSharp.Core.Repository.DbTables; +namespace BotSharp.Abstraction.Repositories.Records; -[Table("Conversation")] -public class ConversationRecord : DbRecord, IBotSharpTable +public class ConversationRecord : RecordBase { [Required] [MaxLength(36)] diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/RecordBase.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/RecordBase.cs new file mode 100644 index 00000000..16e2535a --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/RecordBase.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BotSharp.Abstraction.Repositories.Records +{ + public class RecordBase + { + public string? Id { get; set; } + } +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/DbTables/UserAgentRecord.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/UserAgentRecord.cs similarity index 79% rename from src/Infrastructure/BotSharp.Core/Repository/DbTables/UserAgentRecord.cs rename to src/Infrastructure/BotSharp.Abstraction/Repositories/Records/UserAgentRecord.cs index 4d855d32..6cdf277b 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DbTables/UserAgentRecord.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/UserAgentRecord.cs @@ -1,11 +1,8 @@ using BotSharp.Abstraction.Users.Models; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -namespace BotSharp.Core.Repository.DbTables; +namespace BotSharp.Abstraction.Repositories.Records; -[Table("UserAgent")] -public class UserAgentRecord : DbRecord, IBotSharpTable +public class UserAgentRecord : RecordBase { [Required] [StringLength(36)] diff --git a/src/Infrastructure/BotSharp.Core/Repository/DbTables/UserRecord.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/UserRecord.cs similarity index 86% rename from src/Infrastructure/BotSharp.Core/Repository/DbTables/UserRecord.cs rename to src/Infrastructure/BotSharp.Abstraction/Repositories/Records/UserRecord.cs index 159ce96a..6500ba27 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DbTables/UserRecord.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Records/UserRecord.cs @@ -1,11 +1,8 @@ using BotSharp.Abstraction.Users.Models; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -namespace BotSharp.Core.Repository.DbTables; +namespace BotSharp.Abstraction.Repositories.Records; -[Table("User")] -public class UserRecord : DbRecord, IBotSharpTable +public class UserRecord : RecordBase { [Required] [MaxLength(64)] diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs index cb2dd838..adeefaa3 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs @@ -1,4 +1,6 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Records; namespace BotSharp.Core.Agents.Services; @@ -21,8 +23,8 @@ public partial class AgentService record = AgentRecord.FromAgent(agent); record.Id = Guid.NewGuid().ToString(); - record.CreatedDateTime = DateTime.UtcNow; - record.UpdatedDateTime = DateTime.UtcNow; + record.CreatedTime = DateTime.UtcNow; + record.UpdatedTime = DateTime.UtcNow; var userAgentRecord = new UserAgentRecord { diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs index 420784c3..9a4030b6 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Repositories; using System.IO; namespace BotSharp.Core.Agents.Services; diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index 43559232..c37cd851 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Repositories; using System.IO; namespace BotSharp.Core.Agents.Services; @@ -20,7 +21,7 @@ public partial class AgentService record.Name = agent.Name; record.Description = agent.Description; - record.UpdatedDateTime = DateTime.UtcNow; + record.UpdatedTime = DateTime.UtcNow; }); // Save instruction to file diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs index a07c63ae..97d14dd8 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Repositories; using Microsoft.Extensions.Logging; using System.IO; diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index 6b871db4..c6c51419 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -82,4 +82,8 @@ + + + + diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 9081ca05..95e73f6c 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -1,7 +1,9 @@ using BotSharp.Abstraction.Functions; +using BotSharp.Abstraction.Repositories; using BotSharp.Core.Functions; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; +using DatabaseSettings = BotSharp.Abstraction.Repositories.DatabaseSettings; namespace BotSharp.Core; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 299ad8a6..8c78356c 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -1,4 +1,6 @@ using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Records; namespace BotSharp.Core.Conversations.Services; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index ea3c2603..5f16c3c7 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Repositories; using System.IO; namespace BotSharp.Core.Conversations.Services; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs index 8e0b08dd..1f37ca85 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Repositories; using System.IO; namespace BotSharp.Core.Conversations.Services; diff --git a/src/Infrastructure/BotSharp.Core/Functions/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Functions/RouteToAgentFn.cs index 4c6d1967..35b2d7a8 100644 --- a/src/Infrastructure/BotSharp.Core/Functions/RouteToAgentFn.cs +++ b/src/Infrastructure/BotSharp.Core/Functions/RouteToAgentFn.cs @@ -1,6 +1,7 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions; +using BotSharp.Abstraction.Repositories; using System.IO; namespace BotSharp.Core.Functions; diff --git a/src/Infrastructure/BotSharp.Core/Repository/Abstraction/IBotSharpTable.cs b/src/Infrastructure/BotSharp.Core/Repository/Abstraction/IBotSharpTable.cs deleted file mode 100644 index 2ea3383f..00000000 --- a/src/Infrastructure/BotSharp.Core/Repository/Abstraction/IBotSharpTable.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace BotSharp.Core.Repository.Abstraction; - -public interface IBotSharpTable -{ -} diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index b2b3a411..34b1b6e6 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Records; using Microsoft.EntityFrameworkCore.Infrastructure; namespace BotSharp.Core.Repository; diff --git a/src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs b/src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs deleted file mode 100644 index c32f9a2e..00000000 --- a/src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs +++ /dev/null @@ -1,22 +0,0 @@ -using BotSharp.Abstraction.Conversations.Models; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Bson.Serialization.IdGenerators; - -namespace BotSharp.Core.Repository.Collections; - -public class ConversationCollection : IMongoDbCollection -{ - [BsonId(IdGenerator = typeof(ObjectIdGenerator))] - public ObjectId Id { get; set; } - - public string SessionId { get; set; } - public string UserId { get; set; } - public string Model { get; set; } - - public string Title { get; set; } - public List Messages { get; set; } - - public DateTime CreatedAt { get; set; } - public DateTime UpdatedAt { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs b/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs index 4fa85feb..6cf6069e 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Repositories; using Microsoft.Data.SqlClient; using MySqlConnector; using System.Data.Common; @@ -16,16 +17,7 @@ public static class DataContextHelper AppDomain.CurrentDomain.SetData("Assemblies", settings.Assemblies); var dc = new T(); - if (typeof(T) == typeof(MongoDbContext)) - { - dc.BindDbContext(new DatabaseBind - { - ServiceProvider = serviceProvider, - MasterConnection = new MongoDbConnection(settings.MongoDb.Master), - IsRelational = false - }); - } - else if (typeof(T) == typeof(BotSharpDbContext)) + if (typeof(T) == typeof(BotSharpDbContext)) { if (typeof(Tdb).Name.StartsWith("DbContext4SqlServer")) { diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index b6963794..a34385f5 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Records; using System.IO; using System.Text.Json; diff --git a/src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs b/src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs deleted file mode 100644 index b91b1a4e..00000000 --- a/src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs +++ /dev/null @@ -1,8 +0,0 @@ -using MongoDB.Bson; - -namespace BotSharp.Core.Repository; - -public interface IMongoDbCollection -{ - ObjectId Id { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs deleted file mode 100644 index c92e6f9b..00000000 --- a/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs +++ /dev/null @@ -1,10 +0,0 @@ -using BotSharp.Core.Repository.Collections; -using MongoDB.Driver; - -namespace BotSharp.Core.Repository; - -public class MongoDbContext : Database -{ - public IMongoCollection Conversations - => Collection("conversations"); -} diff --git a/src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs b/src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs deleted file mode 100644 index dadec9b5..00000000 --- a/src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace BotSharp.Core.Repository; - -public class MyDatabaseSettings : DatabaseSettings -{ - public string[] Assemblies { get; set; } - public string FileRepository { get; set; } - public DbConnectionSetting MongoDb { get; set; } - public DbConnectionSetting BotSharp { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs b/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs index 7f79bfcb..7a3f26fe 100644 --- a/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs +++ b/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Repositories.Records; using BotSharp.Abstraction.Users.Models; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; @@ -27,7 +29,7 @@ public class UserService : IUserService } record = UserRecord.FromUser(user); - record.Id = Guid.NewGuid().ToString(); + //record.Id = Guid.NewGuid().ToString(); record.Email = user.Email.ToLower(); record.Salt = Guid.NewGuid().ToString("N"); record.Password = Utilities.HashText(user.Password, record.Salt); diff --git a/src/Infrastructure/BotSharp.Core/Using.cs b/src/Infrastructure/BotSharp.Core/Using.cs index eae0a5a5..0c26934d 100644 --- a/src/Infrastructure/BotSharp.Core/Using.cs +++ b/src/Infrastructure/BotSharp.Core/Using.cs @@ -14,8 +14,6 @@ global using BotSharp.Abstraction.Knowledges; global using BotSharp.Abstraction.Users; global using BotSharp.Abstraction.Utilities; global using BotSharp.Core.Repository; -global using BotSharp.Core.Repository.Abstraction; -global using BotSharp.Core.Repository.DbTables; global using BotSharp.Core.Agents.Services; global using BotSharp.Core.Conversations.Services; global using BotSharp.Core.Infrastructures; diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/BotSharp.Plugin.MongoRepository.csproj b/src/Plugins/BotSharp.Plugin.MongoRepository/BotSharp.Plugin.MongoRepository.csproj new file mode 100644 index 00000000..f4e8050c --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/BotSharp.Plugin.MongoRepository.csproj @@ -0,0 +1,18 @@ + + + + netstandard2.1 + 10.0 + false + 0.9.0 + + + + + + + + + + + diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/AgentCollection.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/AgentCollection.cs new file mode 100644 index 00000000..7187faf9 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/AgentCollection.cs @@ -0,0 +1,14 @@ +namespace BotSharp.Plugin.MongoRepository.Collections +{ + public class AgentCollection : MongoBase + { + public string Name { get; set; } + public string Description { get; set; } + public List Functions { get; set; } + public string Instruction { get; set; } + public List Routes { get; set; } + + public DateTime CreatedTime { get; set; } + public DateTime UpdatedTime { get; set; } + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/ConversationCollection.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/ConversationCollection.cs new file mode 100644 index 00000000..6140f881 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/ConversationCollection.cs @@ -0,0 +1,13 @@ +namespace BotSharp.Plugin.MongoRepository.Collections; + +public class ConversationCollection : MongoBase +{ + public string AgentId { get; set; } + public string UserId { get; set; } + public string Title { get; set; } + public string Dialog { get; set; } + public string State { get; set; } + + public DateTime CreatedTime { get; set; } + public DateTime UpdatedTime { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserAgentCollection.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserAgentCollection.cs new file mode 100644 index 00000000..050b5fcf --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserAgentCollection.cs @@ -0,0 +1,11 @@ +namespace BotSharp.Plugin.MongoRepository.Collections +{ + public class UserAgentCollection : MongoBase + { + public string UserId { get; set; } + public string AgentId { get; set; } + + public DateTime CreatedTime { get; set; } + public DateTime UpdatedTime { get; set; } + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserCollection.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserCollection.cs new file mode 100644 index 00000000..a99aed63 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/Collections/UserCollection.cs @@ -0,0 +1,15 @@ +namespace BotSharp.Plugin.MongoRepository.Collections +{ + public class UserCollection : MongoBase + { + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Salt { get; set; } + public string Password { get; set; } + public string? ExternalId { get; set; } + + public DateTime CreatedTime { get; set; } + public DateTime UpdatedTime { get; set; } + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/MongoBase.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/MongoBase.cs new file mode 100644 index 00000000..98a8f041 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/MongoBase.cs @@ -0,0 +1,11 @@ +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson.Serialization.IdGenerators; + +namespace BotSharp.Plugin.MongoRepository; + +[BsonIgnoreExtraElements(Inherited = true)] +public class MongoBase +{ + [BsonId(IdGenerator = typeof(StringObjectIdGenerator))] + public string Id { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/MongoDbContext.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/MongoDbContext.cs new file mode 100644 index 00000000..23297bd9 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/MongoDbContext.cs @@ -0,0 +1,39 @@ +using BotSharp.Plugin.MongoRepository.Collections; + +namespace BotSharp.Core.Repository; + +public class MongoDbContext +{ + private readonly MongoClient _mongoClient; + private readonly string _mongoDbDatabaseName; + + public MongoDbContext(string mongoDbConnectionString) + { + _mongoClient = new MongoClient(mongoDbConnectionString); + _mongoDbDatabaseName = GetDatabaseName(mongoDbConnectionString); + } + + private string GetDatabaseName(string mongoDbConnectionString) + { + var databaseName = mongoDbConnectionString.Substring(mongoDbConnectionString.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase) + 1); + if (databaseName.Contains("?")) + { + databaseName = databaseName.Substring(0, databaseName.IndexOf("?", StringComparison.InvariantCultureIgnoreCase)); + } + return databaseName; + } + + private IMongoDatabase Database { get { return _mongoClient.GetDatabase(_mongoDbDatabaseName); } } + + public IMongoCollection Agents + => Database.GetCollection("OneBrainAgents"); + + public IMongoCollection Conversations + => Database.GetCollection("OneBrainConversations"); + + public IMongoCollection Users + => Database.GetCollection("OneBrainUsers"); + + public IMongoCollection UserAgents + => Database.GetCollection("OneBrainUserAgents"); +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/MongoRepositoryPlugin.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/MongoRepositoryPlugin.cs new file mode 100644 index 00000000..73517923 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/MongoRepositoryPlugin.cs @@ -0,0 +1,16 @@ +namespace BotSharp.Core.Repository +{ + public class MongoRepositoryPlugin : IBotSharpPlugin + { + public void RegisterDI(IServiceCollection services, IConfiguration config) + { + services.AddSingleton((IServiceProvider x) => + { + var databaseSettings = x.GetRequiredService(); + return new MongoDbContext(databaseSettings.MongoDb); + }); + + services.AddScoped(); + } + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/Repository/MongoRepository.cs new file mode 100644 index 00000000..1cc16c52 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/Repository/MongoRepository.cs @@ -0,0 +1,256 @@ +using BotSharp.Plugin.MongoRepository.Collections; + +namespace BotSharp.Core.Repository +{ + public class MongoRepository : IBotSharpRepository + { + private readonly MongoDbContext _dc; + private readonly IServiceProvider _services; + private UpdateOptions _options; + + public MongoRepository(MongoDbContext dc, IServiceProvider services) + { + _dc = dc; + _services = services; + + _options = new UpdateOptions + { + IsUpsert = true, + }; + } + + private List _agents; + public IQueryable Agent + { + get + { + if (_agents != null) + { + return _agents.AsQueryable(); + } + + var agentDocs = _dc.Agents?.AsQueryable()?.ToList() ?? new List(); + _agents = agentDocs.Select(x => new AgentRecord + { + Id = x.Id?.ToString(), + Name = x.Name, + Description = x.Description, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + return _agents.AsQueryable(); + } + } + + private List _users; + public IQueryable User + { + get + { + if (_users != null) + { + return _users.AsQueryable(); + } + + var userDocs = _dc.Users?.AsQueryable()?.ToList() ?? new List(); + _users = userDocs.Select(x => new UserRecord + { + Id = x.Id?.ToString(), + FirstName = x.FirstName, + LastName = x.LastName, + Email = x.Email, + Password = x.Password, + Salt = x.Salt, + ExternalId = x.ExternalId, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + return _users.AsQueryable(); + } + } + + private List _userAgents; + public IQueryable UserAgent + { + get + { + if (_userAgents != null && _userAgents.Count > 0) + { + return _userAgents.AsQueryable(); + } + + var userDocs = _dc.UserAgents?.AsQueryable()?.ToList() ?? new List(); + _userAgents = userDocs.Select(x => new UserAgentRecord + { + Id = x.Id?.ToString(), + AgentId = x.AgentId, + UserId = x.UserId, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + return _userAgents.AsQueryable(); + } + } + + private List _conversations; + public IQueryable Conversation + { + get + { + if (_conversations != null) + { + return _conversations.AsQueryable(); + } + + var conversationDocs = _dc.Conversations?.AsQueryable()?.ToList() ?? new List(); + _conversations = conversationDocs.Select(x => new ConversationRecord + { + Id = x.Id?.ToString(), + AgentId = x.AgentId, + UserId = x.UserId, + Title = x.Title, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + return _conversations.AsQueryable(); + } + } + + List _changedTableNames = new List(); + public void Add(object entity) + { + if (entity is ConversationRecord conversation) + { + _conversations.Add(conversation); + _changedTableNames.Add(nameof(ConversationRecord)); + } + else if (entity is AgentRecord agent) + { + _agents.Add(agent); + _changedTableNames.Add(nameof(AgentRecord)); + } + else if (entity is UserRecord user) + { + _users.Add(user); + _changedTableNames.Add(nameof(UserRecord)); + } + else if (entity is UserAgentRecord userAgent) + { + _userAgents.Add(userAgent); + _changedTableNames.Add(nameof(UserAgentRecord)); + } + } + + public int Transaction(Action action) + { + _changedTableNames.Clear(); + action(); + + foreach (var table in _changedTableNames) + { + if (table == nameof(ConversationRecord)) + { + var conversations = _conversations.Select(x => new ConversationCollection + { + Id = x.Id.IfNullOrEmptyAs(ObjectId.GenerateNewId().ToString()), + AgentId = x.AgentId, + UserId = x.UserId, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + foreach (var conversation in conversations) + { + var filter = Builders.Filter.Eq(x => x.Id, conversation.Id); + var update = Builders.Update + .Set(x => x.AgentId, conversation.AgentId) + .Set(x => x.UserId, conversation.UserId) + .Set(x => x.CreatedTime, conversation.CreatedTime) + .Set(x => x.UpdatedTime, conversation.UpdatedTime); + _dc.Conversations.UpdateOne(filter, update, _options); + } + } + else if (table == nameof(AgentRecord)) + { + var agents = _agents.Select(x => new AgentCollection + { + Id = x.Id.IfNullOrEmptyAs(ObjectId.GenerateNewId().ToString()), + Name = x.Name, + Description = x.Description, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + foreach (var agent in agents) + { + var filter = Builders.Filter.Eq(x => x.Id, agent.Id); + var update = Builders.Update + .Set(x => x.Name, agent.Name) + .Set(x => x.Description, agent.Description) + .Set(x => x.CreatedTime, agent.CreatedTime) + .Set(x => x.UpdatedTime, agent.UpdatedTime); + _dc.Agents.UpdateOne(filter, update, _options); + } + } + else if (table == nameof(UserRecord)) + { + var users = _users.Select(x => new UserCollection + { + Id = x.Id.IfNullOrEmptyAs(ObjectId.GenerateNewId().ToString()), + FirstName = x.FirstName, + LastName = x.LastName, + Salt = x.Salt, + Password = x.Password, + Email = x.Email, + ExternalId = x.ExternalId, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + foreach (var user in users) + { + var filter = Builders.Filter.Eq(x => x.Id, user.Id); + var update = Builders.Update + .Set(x => x.FirstName, user.FirstName) + .Set(x => x.LastName, user.LastName) + .Set(x => x.Email, user.Email) + .Set(x => x.Salt, user.Salt) + .Set(x => x.Password, user.Password) + .Set(x => x.ExternalId, user.ExternalId) + .Set(x => x.CreatedTime, user.CreatedTime) + .Set(x => x.UpdatedTime, user.UpdatedTime); + _dc.Users.UpdateOne(filter, update, _options); + } + } + else if (table == nameof(UserAgentRecord)) + { + var userAgents = _userAgents.Select(x => new UserAgentCollection + { + Id = x.Id.IfNullOrEmptyAs(ObjectId.GenerateNewId().ToString()), + AgentId = x.AgentId, + UserId = x.UserId, + CreatedTime = x.CreatedTime, + UpdatedTime = x.UpdatedTime + }).ToList(); + + foreach (var userAgent in userAgents) + { + var filter = Builders.Filter.Eq(x => x.Id, userAgent.Id); + var update = Builders.Update + .Set(x => x.AgentId, userAgent.AgentId) + .Set(x => x.UserId, userAgent.UserId) + .Set(x => x.CreatedTime, userAgent.CreatedTime) + .Set(x => x.UpdatedTime, userAgent.UpdatedTime); + _dc.UserAgents.UpdateOne(filter, update, _options); + } + } + } + + return _changedTableNames.Count; + } + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoRepository/Using.cs b/src/Plugins/BotSharp.Plugin.MongoRepository/Using.cs new file mode 100644 index 00000000..e1de896f --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoRepository/Using.cs @@ -0,0 +1,14 @@ +global using System; +global using System.Collections.Generic; +global using System.Text; +global using System.Threading.Tasks; +global using System.Linq; +global using System.Text.Json; +global using BotSharp.Abstraction.Repositories; +global using BotSharp.Abstraction.Repositories.Records; +global using BotSharp.Abstraction.Utilities; +global using BotSharp.Abstraction.Plugins; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; +global using MongoDB.Bson; +global using MongoDB.Driver; \ No newline at end of file