Sql Query Manager

This commit is contained in:
Sedat ÖZTÜRK 2025-12-05 11:56:53 +03:00
parent 9bbf66e94d
commit 3d419a6e7c
61 changed files with 4064 additions and 7 deletions

View file

@ -80,6 +80,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Erp.SqlQueryManager", "Erp.SqlQueryManager", "{2889482E-64CA-4A25-91D8-5B963D83681B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.Domain.Shared", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.Domain.Shared\Erp.SqlQueryManager.Domain.Shared.csproj", "{10D71F44-C9FD-41F2-8F1A-D93FAE3CE696}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.Domain", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.Domain\Erp.SqlQueryManager.Domain.csproj", "{8730045F-91F5-4438-8772-C6E31E89AACC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.Application.Contracts", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.Application.Contracts\Erp.SqlQueryManager.Application.Contracts.csproj", "{B45A3E8B-286B-4A74-9602-FC192ACEE8C4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.Application", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.Application\Erp.SqlQueryManager.Application.csproj", "{ED9C639A-A706-4ECB-9638-A15B3681BDEC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Erp.SqlQueryManager.EntityFrameworkCore", "modules\Erp.SqlQueryManager\Erp.SqlQueryManager.EntityFrameworkCore\Erp.SqlQueryManager.EntityFrameworkCore.csproj", "{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -198,6 +210,26 @@ Global
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9E0D333-60F3-493F-A5B2-5758ACA42A17}.Release|Any CPU.Build.0 = Release|Any CPU
{10D71F44-C9FD-41F2-8F1A-D93FAE3CE696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D71F44-C9FD-41F2-8F1A-D93FAE3CE696}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D71F44-C9FD-41F2-8F1A-D93FAE3CE696}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D71F44-C9FD-41F2-8F1A-D93FAE3CE696}.Release|Any CPU.Build.0 = Release|Any CPU
{8730045F-91F5-4438-8772-C6E31E89AACC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8730045F-91F5-4438-8772-C6E31E89AACC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8730045F-91F5-4438-8772-C6E31E89AACC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8730045F-91F5-4438-8772-C6E31E89AACC}.Release|Any CPU.Build.0 = Release|Any CPU
{B45A3E8B-286B-4A74-9602-FC192ACEE8C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B45A3E8B-286B-4A74-9602-FC192ACEE8C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B45A3E8B-286B-4A74-9602-FC192ACEE8C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B45A3E8B-286B-4A74-9602-FC192ACEE8C4}.Release|Any CPU.Build.0 = Release|Any CPU
{ED9C639A-A706-4ECB-9638-A15B3681BDEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED9C639A-A706-4ECB-9638-A15B3681BDEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED9C639A-A706-4ECB-9638-A15B3681BDEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED9C639A-A706-4ECB-9638-A15B3681BDEC}.Release|Any CPU.Build.0 = Release|Any CPU
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -236,10 +268,14 @@ Global
{631092C7-B59D-4EA7-92D0-5E181AB4F9F6} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
{23659070-58F7-403B-8973-B2E20B5E9BE1} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
{D9E0D333-60F3-493F-A5B2-5758ACA42A17} = {41A473FE-2537-4223-8CF3-A4A2A4A4F41E}
{2889482E-64CA-4A25-91D8-5B963D83681B} = {03E1C8DA-035E-4882-AF81-F392139FCF38}
{10D71F44-C9FD-41F2-8F1A-D93FAE3CE696} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{8730045F-91F5-4438-8772-C6E31E89AACC} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{B45A3E8B-286B-4A74-9602-FC192ACEE8C4} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{ED9C639A-A706-4ECB-9638-A15B3681BDEC} = {2889482E-64CA-4A25-91D8-5B963D83681B}
{1DA666D8-DBFE-40F7-8EBF-95CC892E4EB6} = {2889482E-64CA-4A25-91D8-5B963D83681B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\common.props" />
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Erp.SqlQueryManager</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="9.0.2" />
<PackageReference Include="Volo.Abp.Authorization" Version="9.0.2" />
<ProjectReference Include="..\Erp.SqlQueryManager.Domain.Shared\Erp.SqlQueryManager.Domain.Shared.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,29 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Erp.SqlQueryManager.Application.Contracts;
public interface ISqlFunctionAppService : ICrudAppService<
SqlFunctionDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlFunctionDto,
UpdateSqlFunctionDto>
{
/// <summary>
/// Deploy function to database
/// </summary>
Task<SqlQueryExecutionResultDto> DeployAsync(DeployFunctionDto input);
/// <summary>
/// Check if function exists in database
/// </summary>
Task<bool> CheckExistsAsync(Guid id);
/// <summary>
/// Drop function from database
/// </summary>
Task<SqlQueryExecutionResultDto> DropAsync(Guid id);
}

View file

@ -0,0 +1,39 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Erp.SqlQueryManager.Application.Contracts;
public interface ISqlQueryAppService : ICrudAppService<
SqlQueryDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlQueryDto,
UpdateSqlQueryDto>
{
/// <summary>
/// Execute a SQL query
/// </summary>
Task<SqlQueryExecutionResultDto> ExecuteQueryAsync(ExecuteSqlQueryDto input);
/// <summary>
/// Execute a saved query by ID
/// </summary>
Task<SqlQueryExecutionResultDto> ExecuteSavedQueryAsync(Guid id);
/// <summary>
/// Validate SQL query syntax
/// </summary>
Task<(bool IsValid, string ErrorMessage)> ValidateQueryAsync(string sql);
/// <summary>
/// Activate query
/// </summary>
Task ActivateAsync(Guid id);
/// <summary>
/// Archive query
/// </summary>
Task ArchiveAsync(Guid id);
}

View file

@ -0,0 +1,29 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Erp.SqlQueryManager.Application.Contracts;
public interface ISqlStoredProcedureAppService : ICrudAppService<
SqlStoredProcedureDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlStoredProcedureDto,
UpdateSqlStoredProcedureDto>
{
/// <summary>
/// Deploy stored procedure to database
/// </summary>
Task<SqlQueryExecutionResultDto> DeployAsync(DeployStoredProcedureDto input);
/// <summary>
/// Check if procedure exists in database
/// </summary>
Task<bool> CheckExistsAsync(Guid id);
/// <summary>
/// Drop procedure from database
/// </summary>
Task<SqlQueryExecutionResultDto> DropAsync(Guid id);
}

View file

@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Application.Services;
namespace Erp.SqlQueryManager.Application.Contracts;
public interface ISqlTemplateAppService : IApplicationService
{
/// <summary>
/// Get all available query templates
/// </summary>
Task<List<SqlTemplateDto>> GetQueryTemplatesAsync();
/// <summary>
/// Get stored procedure template
/// </summary>
Task<string> GetStoredProcedureTemplateAsync(string procedureName, string schemaName = "dbo");
/// <summary>
/// Get view template
/// </summary>
Task<string> GetViewTemplateAsync(string viewName, string schemaName = "dbo", bool withSchemaBinding = false);
/// <summary>
/// Get function template
/// </summary>
Task<string> GetFunctionTemplateAsync(string functionName, SqlFunctionType functionType, string schemaName = "dbo");
/// <summary>
/// Get specific query template
/// </summary>
Task<string> GetQueryTemplateAsync(string templateType);
}

View file

@ -0,0 +1,29 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Erp.SqlQueryManager.Application.Contracts;
public interface ISqlViewAppService : ICrudAppService<
SqlViewDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlViewDto,
UpdateSqlViewDto>
{
/// <summary>
/// Deploy view to database
/// </summary>
Task<SqlQueryExecutionResultDto> DeployAsync(DeployViewDto input);
/// <summary>
/// Check if view exists in database
/// </summary>
Task<bool> CheckExistsAsync(Guid id);
/// <summary>
/// Drop view from database
/// </summary>
Task<SqlQueryExecutionResultDto> DropAsync(Guid id);
}

View file

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Application.Dtos;
namespace Erp.SqlQueryManager.Application.Contracts;
public class SqlFunctionDto : FullAuditedEntityDto<Guid>
{
public string FunctionName { get; set; }
public string SchemaName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public SqlFunctionType FunctionType { get; set; }
public string FunctionBody { get; set; }
public string ReturnType { get; set; }
public string DataSourceCode { get; set; }
public SqlQueryStatus Status { get; set; }
public string Category { get; set; }
public bool IsDeployed { get; set; }
public DateTime? LastDeployedAt { get; set; }
public string Parameters { get; set; }
}
public class CreateSqlFunctionDto
{
public string FunctionName { get; set; }
public string SchemaName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public SqlFunctionType FunctionType { get; set; }
public string FunctionBody { get; set; }
public string ReturnType { get; set; }
public string DataSourceCode { get; set; }
public string Category { get; set; }
public string Parameters { get; set; }
}
public class UpdateSqlFunctionDto
{
public string DisplayName { get; set; }
public string Description { get; set; }
public string FunctionBody { get; set; }
public string ReturnType { get; set; }
public string Category { get; set; }
public string Parameters { get; set; }
}
public class DeployFunctionDto
{
public Guid Id { get; set; }
public bool DropIfExists { get; set; }
}

View file

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Application.Dtos;
namespace Erp.SqlQueryManager.Application.Contracts;
public class SqlQueryDto : FullAuditedEntityDto<Guid>
{
public string Code { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string QueryText { get; set; }
public string DataSourceCode { get; set; }
public SqlQueryStatus Status { get; set; }
public string Category { get; set; }
public string Tags { get; set; }
public DateTime? LastExecutedAt { get; set; }
public int ExecutionCount { get; set; }
public bool IsModifyingData { get; set; }
public string Parameters { get; set; }
}
public class CreateSqlQueryDto
{
public string Code { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string QueryText { get; set; }
public string DataSourceCode { get; set; }
public string Category { get; set; }
public string Tags { get; set; }
public bool IsModifyingData { get; set; }
public string Parameters { get; set; }
}
public class UpdateSqlQueryDto
{
public string Code { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string QueryText { get; set; }
public string DataSourceCode { get; set; }
public string Category { get; set; }
public string Tags { get; set; }
public bool IsModifyingData { get; set; }
public string Parameters { get; set; }
}
public class ExecuteSqlQueryDto
{
public string QueryText { get; set; }
public string DataSourceCode { get; set; }
public Dictionary<string, object> Parameters { get; set; }
}
public class SqlQueryExecutionResultDto
{
public bool Success { get; set; }
public string Message { get; set; }
public IEnumerable<dynamic> Data { get; set; }
public int RowsAffected { get; set; }
public long ExecutionTimeMs { get; set; }
public Dictionary<string, object> Metadata { get; set; }
}

View file

@ -0,0 +1,14 @@
using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.Modularity;
namespace Erp.SqlQueryManager;
[DependsOn(
typeof(SqlQueryManagerDomainSharedModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpAuthorizationModule)
)]
public class SqlQueryManagerApplicationContractsModule : AbpModule
{
}

View file

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Application.Dtos;
namespace Erp.SqlQueryManager.Application.Contracts;
public class SqlStoredProcedureDto : FullAuditedEntityDto<Guid>
{
public string ProcedureName { get; set; }
public string SchemaName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string ProcedureBody { get; set; }
public string DataSourceCode { get; set; }
public SqlQueryStatus Status { get; set; }
public string Category { get; set; }
public bool IsDeployed { get; set; }
public DateTime? LastDeployedAt { get; set; }
public string Parameters { get; set; }
}
public class CreateSqlStoredProcedureDto
{
public string ProcedureName { get; set; }
public string SchemaName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string ProcedureBody { get; set; }
public string DataSourceCode { get; set; }
public string Category { get; set; }
public string Parameters { get; set; }
}
public class UpdateSqlStoredProcedureDto
{
public string DisplayName { get; set; }
public string Description { get; set; }
public string ProcedureBody { get; set; }
public string Category { get; set; }
public string Parameters { get; set; }
}
public class DeployStoredProcedureDto
{
public Guid Id { get; set; }
public bool DropIfExists { get; set; }
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace Erp.SqlQueryManager.Application.Contracts;
public class SqlTemplateDto
{
public string Type { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Template { get; set; }
}
public class GetTemplateInput
{
public string TemplateType { get; set; }
public string ObjectName { get; set; }
public string SchemaName { get; set; }
}

View file

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Application.Dtos;
namespace Erp.SqlQueryManager.Application.Contracts;
public class SqlViewDto : FullAuditedEntityDto<Guid>
{
public string ViewName { get; set; }
public string SchemaName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string ViewDefinition { get; set; }
public string DataSourceCode { get; set; }
public SqlQueryStatus Status { get; set; }
public string Category { get; set; }
public bool IsDeployed { get; set; }
public DateTime? LastDeployedAt { get; set; }
public bool WithSchemaBinding { get; set; }
}
public class CreateSqlViewDto
{
public string ViewName { get; set; }
public string SchemaName { get; set; }
public string DisplayName { get; set; }
public string Description { get; set; }
public string ViewDefinition { get; set; }
public string DataSourceCode { get; set; }
public string Category { get; set; }
public bool WithSchemaBinding { get; set; }
}
public class UpdateSqlViewDto
{
public string DisplayName { get; set; }
public string Description { get; set; }
public string ViewDefinition { get; set; }
public string Category { get; set; }
public bool WithSchemaBinding { get; set; }
}
public class DeployViewDto
{
public Guid Id { get; set; }
public bool DropIfExists { get; set; }
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\common.props" />
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Erp.SqlQueryManager</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="9.0.2" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="9.0.2" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="9.0.2" />
<ProjectReference Include="..\Erp.SqlQueryManager.Application.Contracts\Erp.SqlQueryManager.Application.Contracts.csproj" />
<ProjectReference Include="..\Erp.SqlQueryManager.Domain\Erp.SqlQueryManager.Domain.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,139 @@
using System;
using System.Threading.Tasks;
using Erp.SqlQueryManager.Application.Contracts;
using Erp.SqlQueryManager.Domain.Entities;
using Erp.SqlQueryManager.Domain.Services;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Erp.SqlQueryManager.Application;
public class SqlFunctionAppService : CrudAppService<
SqlFunction,
SqlFunctionDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlFunctionDto,
UpdateSqlFunctionDto>, ISqlFunctionAppService
{
private readonly ISqlExecutorService _sqlExecutorService;
public SqlFunctionAppService(
IRepository<SqlFunction, Guid> repository,
ISqlExecutorService sqlExecutorService) : base(repository)
{
_sqlExecutorService = sqlExecutorService;
}
public override async Task<SqlFunctionDto> CreateAsync(CreateSqlFunctionDto input)
{
var entity = new SqlFunction(
GuidGenerator.Create(),
input.FunctionName,
input.SchemaName ?? "dbo",
input.DisplayName,
input.FunctionType,
input.FunctionBody,
input.ReturnType,
input.DataSourceCode,
CurrentTenant.Id)
{
Description = input.Description,
Category = input.Category,
Parameters = input.Parameters
};
await Repository.InsertAsync(entity);
return ObjectMapper.Map<SqlFunction, SqlFunctionDto>(entity);
}
public override async Task<SqlFunctionDto> UpdateAsync(Guid id, UpdateSqlFunctionDto input)
{
var entity = await Repository.GetAsync(id);
entity.DisplayName = input.DisplayName;
entity.Description = input.Description;
entity.UpdateBody(input.FunctionBody);
entity.ReturnType = input.ReturnType;
entity.Category = input.Category;
entity.Parameters = input.Parameters;
await Repository.UpdateAsync(entity);
return ObjectMapper.Map<SqlFunction, SqlFunctionDto>(entity);
}
public async Task<SqlQueryExecutionResultDto> DeployAsync(DeployFunctionDto input)
{
var function = await Repository.GetAsync(input.Id);
// Drop if exists and requested
if (input.DropIfExists)
{
var objectType = function.FunctionType.ToString().ToUpperInvariant().Replace("FUNCTION", "_FUNCTION");
await _sqlExecutorService.DropObjectAsync(
function.FunctionName,
$"SQL_{objectType}",
function.DataSourceCode,
function.SchemaName);
}
// Deploy the function
var result = await _sqlExecutorService.DeployFunctionAsync(
function.FunctionBody,
function.DataSourceCode);
if (result.Success)
{
function.MarkAsDeployed();
await Repository.UpdateAsync(function);
}
return MapExecutionResult(result);
}
public async Task<bool> CheckExistsAsync(Guid id)
{
var function = await Repository.GetAsync(id);
var objectType = function.FunctionType.ToString().ToUpperInvariant().Replace("FUNCTION", "_FUNCTION");
return await _sqlExecutorService.CheckObjectExistsAsync(
function.FunctionName,
$"SQL_{objectType}",
function.DataSourceCode,
function.SchemaName);
}
public async Task<SqlQueryExecutionResultDto> DropAsync(Guid id)
{
var function = await Repository.GetAsync(id);
var objectType = function.FunctionType.ToString().ToUpperInvariant().Replace("FUNCTION", "_FUNCTION");
var result = await _sqlExecutorService.DropObjectAsync(
function.FunctionName,
$"SQL_{objectType}",
function.DataSourceCode,
function.SchemaName);
if (result.Success)
{
function.IsDeployed = false;
await Repository.UpdateAsync(function);
}
return MapExecutionResult(result);
}
private SqlQueryExecutionResultDto MapExecutionResult(SqlExecutionResult result)
{
return new SqlQueryExecutionResultDto
{
Success = result.Success,
Message = result.Message,
Data = result.Data,
RowsAffected = result.RowsAffected,
ExecutionTimeMs = result.ExecutionTimeMs,
Metadata = result.Metadata
};
}
}

View file

@ -0,0 +1,124 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Erp.SqlQueryManager.Application.Contracts;
using Erp.SqlQueryManager.Domain.Entities;
using Erp.SqlQueryManager.Domain.Services;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Erp.SqlQueryManager.Application;
public class SqlQueryAppService : CrudAppService<
SqlQuery,
SqlQueryDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlQueryDto,
UpdateSqlQueryDto>, ISqlQueryAppService
{
private readonly ISqlExecutorService _sqlExecutorService;
public SqlQueryAppService(
IRepository<SqlQuery, Guid> repository,
ISqlExecutorService sqlExecutorService) : base(repository)
{
_sqlExecutorService = sqlExecutorService;
}
public override async Task<SqlQueryDto> CreateAsync(CreateSqlQueryDto input)
{
var entity = new SqlQuery(
GuidGenerator.Create(),
input.Code,
input.Name,
input.QueryText,
input.DataSourceCode,
CurrentTenant.Id)
{
Description = input.Description,
Category = input.Category,
Tags = input.Tags,
IsModifyingData = input.IsModifyingData,
Parameters = input.Parameters
};
await Repository.InsertAsync(entity);
return ObjectMapper.Map<SqlQuery, SqlQueryDto>(entity);
}
public override async Task<SqlQueryDto> UpdateAsync(Guid id, UpdateSqlQueryDto input)
{
var entity = await Repository.GetAsync(id);
entity.Name = input.Name;
entity.Description = input.Description;
entity.UpdateQueryText(input.QueryText);
entity.DataSourceCode = input.DataSourceCode;
entity.Category = input.Category;
entity.Tags = input.Tags;
entity.IsModifyingData = input.IsModifyingData;
entity.Parameters = input.Parameters;
await Repository.UpdateAsync(entity);
return ObjectMapper.Map<SqlQuery, SqlQueryDto>(entity);
}
public async Task<SqlQueryExecutionResultDto> ExecuteQueryAsync(ExecuteSqlQueryDto input)
{
var result = input.QueryText.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase)
? await _sqlExecutorService.ExecuteQueryAsync(input.QueryText, input.DataSourceCode, input.Parameters)
: await _sqlExecutorService.ExecuteNonQueryAsync(input.QueryText, input.DataSourceCode, input.Parameters);
return MapExecutionResult(result);
}
public async Task<SqlQueryExecutionResultDto> ExecuteSavedQueryAsync(Guid id)
{
var query = await Repository.GetAsync(id);
var result = query.IsModifyingData
? await _sqlExecutorService.ExecuteNonQueryAsync(query.QueryText, query.DataSourceCode)
: await _sqlExecutorService.ExecuteQueryAsync(query.QueryText, query.DataSourceCode);
// Update execution statistics
query.MarkAsExecuted();
await Repository.UpdateAsync(query);
return MapExecutionResult(result);
}
public async Task<(bool IsValid, string ErrorMessage)> ValidateQueryAsync(string sql)
{
return await _sqlExecutorService.ValidateSqlAsync(sql);
}
public async Task ActivateAsync(Guid id)
{
var entity = await Repository.GetAsync(id);
entity.Activate();
await Repository.UpdateAsync(entity);
}
public async Task ArchiveAsync(Guid id)
{
var entity = await Repository.GetAsync(id);
entity.Archive();
await Repository.UpdateAsync(entity);
}
private SqlQueryExecutionResultDto MapExecutionResult(SqlExecutionResult result)
{
return new SqlQueryExecutionResultDto
{
Success = result.Success,
Message = result.Message,
Data = result.Data,
RowsAffected = result.RowsAffected,
ExecutionTimeMs = result.ExecutionTimeMs,
Metadata = result.Metadata
};
}
}

View file

@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace Erp.SqlQueryManager;
[DependsOn(
typeof(SqlQueryManagerDomainModule),
typeof(SqlQueryManagerApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]
public class SqlQueryManagerApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<SqlQueryManagerApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<SqlQueryManagerApplicationModule>(validate: true);
});
}
}

View file

@ -0,0 +1,87 @@
using AutoMapper;
using Erp.SqlQueryManager.Application.Contracts;
using Erp.SqlQueryManager.Domain.Entities;
using Volo.Abp.AutoMapper;
namespace Erp.SqlQueryManager.Application;
public class SqlQueryManagerAutoMapperProfile : Profile
{
public SqlQueryManagerAutoMapperProfile()
{
CreateMap<SqlQuery, SqlQueryDto>();
CreateMap<CreateSqlQueryDto, SqlQuery>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.Status)
.Ignore(x => x.LastExecutedAt)
.Ignore(x => x.ExecutionCount);
CreateMap<UpdateSqlQueryDto, SqlQuery>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.Status)
.Ignore(x => x.LastExecutedAt)
.Ignore(x => x.ExecutionCount);
CreateMap<SqlStoredProcedure, SqlStoredProcedureDto>();
CreateMap<CreateSqlStoredProcedureDto, SqlStoredProcedure>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.Status)
.Ignore(x => x.IsDeployed)
.Ignore(x => x.LastDeployedAt);
CreateMap<UpdateSqlStoredProcedureDto, SqlStoredProcedure>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.ProcedureName)
.Ignore(x => x.SchemaName)
.Ignore(x => x.DataSourceCode)
.Ignore(x => x.Status)
.Ignore(x => x.IsDeployed)
.Ignore(x => x.LastDeployedAt);
CreateMap<SqlView, SqlViewDto>();
CreateMap<CreateSqlViewDto, SqlView>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.Status)
.Ignore(x => x.IsDeployed)
.Ignore(x => x.LastDeployedAt);
CreateMap<UpdateSqlViewDto, SqlView>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.ViewName)
.Ignore(x => x.SchemaName)
.Ignore(x => x.DataSourceCode)
.Ignore(x => x.Status)
.Ignore(x => x.IsDeployed)
.Ignore(x => x.LastDeployedAt);
CreateMap<SqlFunction, SqlFunctionDto>();
CreateMap<CreateSqlFunctionDto, SqlFunction>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.Status)
.Ignore(x => x.IsDeployed)
.Ignore(x => x.LastDeployedAt);
CreateMap<UpdateSqlFunctionDto, SqlFunction>()
.IgnoreFullAuditedObjectProperties()
.Ignore(x => x.Id)
.Ignore(x => x.TenantId)
.Ignore(x => x.FunctionName)
.Ignore(x => x.SchemaName)
.Ignore(x => x.FunctionType)
.Ignore(x => x.DataSourceCode)
.Ignore(x => x.Status)
.Ignore(x => x.IsDeployed)
.Ignore(x => x.LastDeployedAt);
}
}

View file

@ -0,0 +1,134 @@
using System;
using System.Threading.Tasks;
using Erp.SqlQueryManager.Application.Contracts;
using Erp.SqlQueryManager.Domain.Entities;
using Erp.SqlQueryManager.Domain.Services;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Erp.SqlQueryManager.Application;
public class SqlStoredProcedureAppService : CrudAppService<
SqlStoredProcedure,
SqlStoredProcedureDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlStoredProcedureDto,
UpdateSqlStoredProcedureDto>, ISqlStoredProcedureAppService
{
private readonly ISqlExecutorService _sqlExecutorService;
public SqlStoredProcedureAppService(
IRepository<SqlStoredProcedure, Guid> repository,
ISqlExecutorService sqlExecutorService) : base(repository)
{
_sqlExecutorService = sqlExecutorService;
}
public override async Task<SqlStoredProcedureDto> CreateAsync(CreateSqlStoredProcedureDto input)
{
var entity = new SqlStoredProcedure(
GuidGenerator.Create(),
input.ProcedureName,
input.SchemaName ?? "dbo",
input.DisplayName,
input.ProcedureBody,
input.DataSourceCode,
CurrentTenant.Id)
{
Description = input.Description,
Category = input.Category,
Parameters = input.Parameters
};
await Repository.InsertAsync(entity);
return ObjectMapper.Map<SqlStoredProcedure, SqlStoredProcedureDto>(entity);
}
public override async Task<SqlStoredProcedureDto> UpdateAsync(Guid id, UpdateSqlStoredProcedureDto input)
{
var entity = await Repository.GetAsync(id);
entity.DisplayName = input.DisplayName;
entity.Description = input.Description;
entity.UpdateBody(input.ProcedureBody);
entity.Category = input.Category;
entity.Parameters = input.Parameters;
await Repository.UpdateAsync(entity);
return ObjectMapper.Map<SqlStoredProcedure, SqlStoredProcedureDto>(entity);
}
public async Task<SqlQueryExecutionResultDto> DeployAsync(DeployStoredProcedureDto input)
{
var procedure = await Repository.GetAsync(input.Id);
// Drop if exists and requested
if (input.DropIfExists)
{
await _sqlExecutorService.DropObjectAsync(
procedure.ProcedureName,
"SQL_STORED_PROCEDURE",
procedure.DataSourceCode,
procedure.SchemaName);
}
// Deploy the procedure
var result = await _sqlExecutorService.DeployStoredProcedureAsync(
procedure.ProcedureBody,
procedure.DataSourceCode);
if (result.Success)
{
procedure.MarkAsDeployed();
await Repository.UpdateAsync(procedure);
}
return MapExecutionResult(result);
}
public async Task<bool> CheckExistsAsync(Guid id)
{
var procedure = await Repository.GetAsync(id);
return await _sqlExecutorService.CheckObjectExistsAsync(
procedure.ProcedureName,
"SQL_STORED_PROCEDURE",
procedure.DataSourceCode,
procedure.SchemaName);
}
public async Task<SqlQueryExecutionResultDto> DropAsync(Guid id)
{
var procedure = await Repository.GetAsync(id);
var result = await _sqlExecutorService.DropObjectAsync(
procedure.ProcedureName,
"SQL_STORED_PROCEDURE",
procedure.DataSourceCode,
procedure.SchemaName);
if (result.Success)
{
procedure.IsDeployed = false;
await Repository.UpdateAsync(procedure);
}
return MapExecutionResult(result);
}
private SqlQueryExecutionResultDto MapExecutionResult(SqlExecutionResult result)
{
return new SqlQueryExecutionResultDto
{
Success = result.Success,
Message = result.Message,
Data = result.Data,
RowsAffected = result.RowsAffected,
ExecutionTimeMs = result.ExecutionTimeMs,
Metadata = result.Metadata
};
}
}

View file

@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Erp.SqlQueryManager.Application.Contracts;
using Erp.SqlQueryManager.Domain.Services;
using Erp.SqlQueryManager.Domain.Shared;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Services;
namespace Erp.SqlQueryManager.Application;
public class SqlTemplateAppService : ApplicationService, ISqlTemplateAppService
{
private readonly ISqlTemplateProvider _templateProvider;
public SqlTemplateAppService(ISqlTemplateProvider templateProvider)
{
_templateProvider = templateProvider;
}
public Task<List<SqlTemplateDto>> GetQueryTemplatesAsync()
{
var templates = _templateProvider.GetAvailableQueryTemplates()
.Select(t => new SqlTemplateDto
{
Type = t.Type,
Name = t.Name,
Description = t.Description,
Template = _templateProvider.GetQueryTemplate(t.Type)
})
.ToList();
return Task.FromResult(templates);
}
public Task<string> GetStoredProcedureTemplateAsync(string procedureName, string schemaName = "dbo")
{
var template = _templateProvider.GetStoredProcedureTemplate(procedureName, schemaName);
return Task.FromResult(template);
}
public Task<string> GetViewTemplateAsync(string viewName, string schemaName = "dbo", bool withSchemaBinding = false)
{
var template = _templateProvider.GetViewTemplate(viewName, schemaName, withSchemaBinding);
return Task.FromResult(template);
}
public Task<string> GetFunctionTemplateAsync(string functionName, SqlFunctionType functionType, string schemaName = "dbo")
{
var template = _templateProvider.GetFunctionTemplate(functionName, functionType, schemaName);
return Task.FromResult(template);
}
public Task<string> GetQueryTemplateAsync(string templateType)
{
var template = _templateProvider.GetQueryTemplate(templateType);
return Task.FromResult(template);
}
}

View file

@ -0,0 +1,133 @@
using System;
using System.Threading.Tasks;
using Erp.SqlQueryManager.Application.Contracts;
using Erp.SqlQueryManager.Domain.Entities;
using Erp.SqlQueryManager.Domain.Services;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Erp.SqlQueryManager.Application;
public class SqlViewAppService : CrudAppService<
SqlView,
SqlViewDto,
Guid,
PagedAndSortedResultRequestDto,
CreateSqlViewDto,
UpdateSqlViewDto>, ISqlViewAppService
{
private readonly ISqlExecutorService _sqlExecutorService;
public SqlViewAppService(
IRepository<SqlView, Guid> repository,
ISqlExecutorService sqlExecutorService) : base(repository)
{
_sqlExecutorService = sqlExecutorService;
}
public override async Task<SqlViewDto> CreateAsync(CreateSqlViewDto input)
{
var entity = new SqlView(
GuidGenerator.Create(),
input.ViewName,
input.SchemaName ?? "dbo",
input.DisplayName,
input.ViewDefinition,
input.DataSourceCode,
CurrentTenant.Id)
{
Description = input.Description,
Category = input.Category,
WithSchemaBinding = input.WithSchemaBinding
};
await Repository.InsertAsync(entity);
return ObjectMapper.Map<SqlView, SqlViewDto>(entity);
}
public override async Task<SqlViewDto> UpdateAsync(Guid id, UpdateSqlViewDto input)
{
var entity = await Repository.GetAsync(id);
entity.DisplayName = input.DisplayName;
entity.Description = input.Description;
entity.UpdateDefinition(input.ViewDefinition);
entity.Category = input.Category;
entity.WithSchemaBinding = input.WithSchemaBinding;
await Repository.UpdateAsync(entity);
return ObjectMapper.Map<SqlView, SqlViewDto>(entity);
}
public async Task<SqlQueryExecutionResultDto> DeployAsync(DeployViewDto input)
{
var view = await Repository.GetAsync(input.Id);
// Drop if exists and requested
if (input.DropIfExists)
{
await _sqlExecutorService.DropObjectAsync(
view.ViewName,
"VIEW",
view.DataSourceCode,
view.SchemaName);
}
// Deploy the view
var result = await _sqlExecutorService.DeployViewAsync(
view.ViewDefinition,
view.DataSourceCode);
if (result.Success)
{
view.MarkAsDeployed();
await Repository.UpdateAsync(view);
}
return MapExecutionResult(result);
}
public async Task<bool> CheckExistsAsync(Guid id)
{
var view = await Repository.GetAsync(id);
return await _sqlExecutorService.CheckObjectExistsAsync(
view.ViewName,
"VIEW",
view.DataSourceCode,
view.SchemaName);
}
public async Task<SqlQueryExecutionResultDto> DropAsync(Guid id)
{
var view = await Repository.GetAsync(id);
var result = await _sqlExecutorService.DropObjectAsync(
view.ViewName,
"VIEW",
view.DataSourceCode,
view.SchemaName);
if (result.Success)
{
view.IsDeployed = false;
await Repository.UpdateAsync(view);
}
return MapExecutionResult(result);
}
private SqlQueryExecutionResultDto MapExecutionResult(SqlExecutionResult result)
{
return new SqlQueryExecutionResultDto
{
Success = result.Success,
Message = result.Message,
Data = result.Data,
RowsAffected = result.RowsAffected,
ExecutionTimeMs = result.ExecutionTimeMs,
Metadata = result.Metadata
};
}
}

View file

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\common.props" />
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<RootNamespace>Erp.SqlQueryManager</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain.Shared" Version="9.0.2" />
<PackageReference Include="Volo.Abp.Validation" Version="9.0.2" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\SqlQueryManager\*.json" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,8 @@
using Volo.Abp.Localization;
namespace Erp.SqlQueryManager.Domain.Shared;
[LocalizationResourceName("SqlQueryManager")]
public class ErpSqlQueryManagerResource
{
}

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,23 @@
namespace Erp.SqlQueryManager.Domain.Shared;
public enum SqlObjectType
{
Query = 1,
StoredProcedure = 2,
View = 3,
Function = 4
}
public enum SqlFunctionType
{
ScalarFunction = 1,
TableValuedFunction = 2,
InlineTableValuedFunction = 3
}
public enum SqlQueryStatus
{
Draft = 1,
Active = 2,
Archived = 3
}

View file

@ -0,0 +1,34 @@
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Domain;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.Validation;
using Volo.Abp.VirtualFileSystem;
namespace Erp.SqlQueryManager;
[DependsOn(
typeof(AbpValidationModule),
typeof(AbpDddDomainSharedModule)
)]
public class SqlQueryManagerDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<SqlQueryManagerDomainSharedModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<ErpSqlQueryManagerResource>("en");
});
Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("SqlQueryManager", typeof(ErpSqlQueryManagerResource));
});
}
}

View file

@ -0,0 +1,11 @@
namespace Erp.SqlQueryManager.Domain.Shared;
public static class SqlQueryManagerErrorCodes
{
public const string InvalidSqlQuery = "SqlQueryManager:InvalidSqlQuery";
public const string DataSourceNotFound = "SqlQueryManager:DataSourceNotFound";
public const string ExecutionFailed = "SqlQueryManager:ExecutionFailed";
public const string PermissionDenied = "SqlQueryManager:PermissionDenied";
public const string InvalidObjectName = "SqlQueryManager:InvalidObjectName";
public const string ObjectAlreadyExists = "SqlQueryManager:ObjectAlreadyExists";
}

View file

@ -0,0 +1,57 @@
using Volo.Abp.Reflection;
namespace Erp.SqlQueryManager.Domain.Shared;
public static class SqlQueryManagerPermissions
{
public const string GroupName = "SqlQueryManager";
public static class SqlQuery
{
public const string Default = GroupName + ".SqlQuery";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string Execute = Default + ".Execute";
}
public static class SqlStoredProcedure
{
public const string Default = GroupName + ".SqlStoredProcedure";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string Deploy = Default + ".Deploy";
public const string Drop = Default + ".Drop";
}
public static class SqlView
{
public const string Default = GroupName + ".SqlView";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string Deploy = Default + ".Deploy";
public const string Drop = Default + ".Drop";
}
public static class SqlFunction
{
public const string Default = GroupName + ".SqlFunction";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string Deploy = Default + ".Deploy";
public const string Drop = Default + ".Drop";
}
public static class Templates
{
public const string Default = GroupName + ".Templates";
}
public static string[] GetAll()
{
return ReflectionHelper.GetPublicConstantsRecursively(typeof(SqlQueryManagerPermissions));
}
}

View file

@ -0,0 +1,120 @@
using System;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Erp.SqlQueryManager.Domain.Entities;
/// <summary>
/// SQL Function entity for creating and managing database functions
/// </summary>
public class SqlFunction : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
/// <summary>
/// Function name in database
/// </summary>
public string FunctionName { get; set; }
/// <summary>
/// Schema name (default: dbo)
/// </summary>
public string SchemaName { get; set; }
/// <summary>
/// Display name
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// Description
/// </summary>
public string Description { get; set; }
/// <summary>
/// Function type
/// </summary>
public SqlFunctionType FunctionType { get; set; }
/// <summary>
/// Full function definition (CREATE/ALTER)
/// </summary>
public string FunctionBody { get; set; }
/// <summary>
/// Return type definition
/// </summary>
public string ReturnType { get; set; }
/// <summary>
/// DataSource code
/// </summary>
public string DataSourceCode { get; set; }
/// <summary>
/// Status
/// </summary>
public SqlQueryStatus Status { get; set; }
/// <summary>
/// Category
/// </summary>
public string Category { get; set; }
/// <summary>
/// Whether function exists in database
/// </summary>
public bool IsDeployed { get; set; }
/// <summary>
/// Last deployment time
/// </summary>
public DateTime? LastDeployedAt { get; set; }
/// <summary>
/// Parameter definitions (JSON)
/// </summary>
public string Parameters { get; set; }
protected SqlFunction()
{
}
public SqlFunction(
Guid id,
string functionName,
string schemaName,
string displayName,
SqlFunctionType functionType,
string functionBody,
string returnType,
string dataSourceCode,
Guid? tenantId = null) : base(id)
{
FunctionName = functionName;
SchemaName = schemaName ?? "dbo";
DisplayName = displayName;
FunctionType = functionType;
FunctionBody = functionBody;
ReturnType = returnType;
DataSourceCode = dataSourceCode;
TenantId = tenantId;
Status = SqlQueryStatus.Draft;
IsDeployed = false;
}
public void UpdateBody(string body)
{
FunctionBody = body;
}
public void MarkAsDeployed()
{
IsDeployed = true;
LastDeployedAt = DateTime.UtcNow;
Status = SqlQueryStatus.Active;
}
public string GetFullName() => $"{SchemaName}.{FunctionName}";
}

View file

@ -0,0 +1,116 @@
using System;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Erp.SqlQueryManager.Domain.Entities;
/// <summary>
/// SQL Query entity for storing and managing SQL queries
/// </summary>
public class SqlQuery : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
/// <summary>
/// Unique code for the query
/// </summary>
public string Code { get; set; }
/// <summary>
/// Display name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Description of the query
/// </summary>
public string Description { get; set; }
/// <summary>
/// SQL query content
/// </summary>
public string QueryText { get; set; }
/// <summary>
/// DataSource code to use for execution
/// </summary>
public string DataSourceCode { get; set; }
/// <summary>
/// Query status
/// </summary>
public SqlQueryStatus Status { get; set; }
/// <summary>
/// Category for organization
/// </summary>
public string Category { get; set; }
/// <summary>
/// Tags for filtering
/// </summary>
public string Tags { get; set; }
/// <summary>
/// Last execution time
/// </summary>
public DateTime? LastExecutedAt { get; set; }
/// <summary>
/// Execution count
/// </summary>
public int ExecutionCount { get; set; }
/// <summary>
/// Whether query modifies data
/// </summary>
public bool IsModifyingData { get; set; }
/// <summary>
/// Expected parameter definitions (JSON format)
/// </summary>
public string Parameters { get; set; }
protected SqlQuery()
{
}
public SqlQuery(
Guid id,
string code,
string name,
string queryText,
string dataSourceCode,
Guid? tenantId = null) : base(id)
{
Code = code;
Name = name;
QueryText = queryText;
DataSourceCode = dataSourceCode;
TenantId = tenantId;
Status = SqlQueryStatus.Draft;
ExecutionCount = 0;
}
public void UpdateQueryText(string queryText)
{
QueryText = queryText;
}
public void MarkAsExecuted()
{
LastExecutedAt = DateTime.UtcNow;
ExecutionCount++;
}
public void Activate()
{
Status = SqlQueryStatus.Active;
}
public void Archive()
{
Status = SqlQueryStatus.Archived;
}
}

View file

@ -0,0 +1,106 @@
using System;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Erp.SqlQueryManager.Domain.Entities;
/// <summary>
/// SQL Stored Procedure entity for creating and managing stored procedures
/// </summary>
public class SqlStoredProcedure : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
/// <summary>
/// Procedure name in database
/// </summary>
public string ProcedureName { get; set; }
/// <summary>
/// Schema name (default: dbo)
/// </summary>
public string SchemaName { get; set; }
/// <summary>
/// Display name
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// Description
/// </summary>
public string Description { get; set; }
/// <summary>
/// Full procedure definition (CREATE/ALTER)
/// </summary>
public string ProcedureBody { get; set; }
/// <summary>
/// DataSource code
/// </summary>
public string DataSourceCode { get; set; }
/// <summary>
/// Status
/// </summary>
public SqlQueryStatus Status { get; set; }
/// <summary>
/// Category
/// </summary>
public string Category { get; set; }
/// <summary>
/// Whether procedure exists in database
/// </summary>
public bool IsDeployed { get; set; }
/// <summary>
/// Last deployment time
/// </summary>
public DateTime? LastDeployedAt { get; set; }
/// <summary>
/// Parameter definitions (JSON)
/// </summary>
public string Parameters { get; set; }
protected SqlStoredProcedure()
{
}
public SqlStoredProcedure(
Guid id,
string procedureName,
string schemaName,
string displayName,
string procedureBody,
string dataSourceCode,
Guid? tenantId = null) : base(id)
{
ProcedureName = procedureName;
SchemaName = schemaName ?? "dbo";
DisplayName = displayName;
ProcedureBody = procedureBody;
DataSourceCode = dataSourceCode;
TenantId = tenantId;
Status = SqlQueryStatus.Draft;
IsDeployed = false;
}
public void UpdateBody(string body)
{
ProcedureBody = body;
}
public void MarkAsDeployed()
{
IsDeployed = true;
LastDeployedAt = DateTime.UtcNow;
Status = SqlQueryStatus.Active;
}
public string GetFullName() => $"{SchemaName}.{ProcedureName}";
}

View file

@ -0,0 +1,107 @@
using System;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Erp.SqlQueryManager.Domain.Entities;
/// <summary>
/// SQL View entity for creating and managing database views
/// </summary>
public class SqlView : FullAuditedEntity<Guid>, IMultiTenant
{
public Guid? TenantId { get; set; }
/// <summary>
/// View name in database
/// </summary>
public string ViewName { get; set; }
/// <summary>
/// Schema name (default: dbo)
/// </summary>
public string SchemaName { get; set; }
/// <summary>
/// Display name
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// Description
/// </summary>
public string Description { get; set; }
/// <summary>
/// View definition (SELECT statement)
/// </summary>
public string ViewDefinition { get; set; }
/// <summary>
/// DataSource code
/// </summary>
public string DataSourceCode { get; set; }
/// <summary>
/// Status
/// </summary>
public SqlQueryStatus Status { get; set; }
/// <summary>
/// Category
/// </summary>
public string Category { get; set; }
/// <summary>
/// Whether view exists in database
/// </summary>
public bool IsDeployed { get; set; }
/// <summary>
/// Last deployment time
/// </summary>
public DateTime? LastDeployedAt { get; set; }
/// <summary>
/// Whether to use WITH SCHEMABINDING
/// </summary>
public bool WithSchemaBinding { get; set; }
protected SqlView()
{
}
public SqlView(
Guid id,
string viewName,
string schemaName,
string displayName,
string viewDefinition,
string dataSourceCode,
Guid? tenantId = null) : base(id)
{
ViewName = viewName;
SchemaName = schemaName ?? "dbo";
DisplayName = displayName;
ViewDefinition = viewDefinition;
DataSourceCode = dataSourceCode;
TenantId = tenantId;
Status = SqlQueryStatus.Draft;
IsDeployed = false;
WithSchemaBinding = false;
}
public void UpdateDefinition(string definition)
{
ViewDefinition = definition;
}
public void MarkAsDeployed()
{
IsDeployed = true;
LastDeployedAt = DateTime.UtcNow;
Status = SqlQueryStatus.Active;
}
public string GetFullName() => $"{SchemaName}.{ViewName}";
}

View file

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\common.props" />
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Erp.SqlQueryManager</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="9.0.2" />
<ProjectReference Include="..\Erp.SqlQueryManager.Domain.Shared\Erp.SqlQueryManager.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\src\Erp.Platform.Domain\Erp.Platform.Domain.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,96 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Erp.SqlQueryManager.Domain.Services;
/// <summary>
/// Result of SQL query execution
/// </summary>
public class SqlExecutionResult
{
public bool Success { get; set; }
public string Message { get; set; }
public IEnumerable<dynamic> Data { get; set; }
public int RowsAffected { get; set; }
public long ExecutionTimeMs { get; set; }
public Dictionary<string, object> Metadata { get; set; }
public SqlExecutionResult()
{
Metadata = new Dictionary<string, object>();
}
}
/// <summary>
/// Service for executing SQL commands
/// </summary>
public interface ISqlExecutorService
{
/// <summary>
/// Execute a SELECT query and return results
/// </summary>
Task<SqlExecutionResult> ExecuteQueryAsync(
string sql,
string dataSourceCode,
Dictionary<string, object> parameters = null);
/// <summary>
/// Execute a non-query command (INSERT, UPDATE, DELETE)
/// </summary>
Task<SqlExecutionResult> ExecuteNonQueryAsync(
string sql,
string dataSourceCode,
Dictionary<string, object> parameters = null);
/// <summary>
/// Execute scalar query (returns single value)
/// </summary>
Task<SqlExecutionResult> ExecuteScalarAsync<T>(
string sql,
string dataSourceCode,
Dictionary<string, object> parameters = null);
/// <summary>
/// Deploy stored procedure to database
/// </summary>
Task<SqlExecutionResult> DeployStoredProcedureAsync(
string procedureBody,
string dataSourceCode);
/// <summary>
/// Deploy view to database
/// </summary>
Task<SqlExecutionResult> DeployViewAsync(
string viewDefinition,
string dataSourceCode);
/// <summary>
/// Deploy function to database
/// </summary>
Task<SqlExecutionResult> DeployFunctionAsync(
string functionBody,
string dataSourceCode);
/// <summary>
/// Check if database object exists
/// </summary>
Task<bool> CheckObjectExistsAsync(
string objectName,
string objectType,
string dataSourceCode,
string schemaName = "dbo");
/// <summary>
/// Drop database object
/// </summary>
Task<SqlExecutionResult> DropObjectAsync(
string objectName,
string objectType,
string dataSourceCode,
string schemaName = "dbo");
/// <summary>
/// Validate SQL syntax (basic validation)
/// </summary>
Task<(bool IsValid, string ErrorMessage)> ValidateSqlAsync(string sql);
}

View file

@ -0,0 +1,42 @@
using System.Collections.Generic;
using Erp.SqlQueryManager.Domain.Shared;
namespace Erp.SqlQueryManager.Domain.Services;
/// <summary>
/// Provides SQL templates for creating database objects
/// </summary>
public interface ISqlTemplateProvider
{
/// <summary>
/// Get stored procedure template
/// </summary>
string GetStoredProcedureTemplate(string procedureName, string schemaName = "dbo");
/// <summary>
/// Get view template
/// </summary>
string GetViewTemplate(string viewName, string schemaName = "dbo", bool withSchemaBinding = false);
/// <summary>
/// Get function template
/// </summary>
string GetFunctionTemplate(string functionName, SqlFunctionType functionType, string schemaName = "dbo");
/// <summary>
/// Get query template with common patterns
/// </summary>
string GetQueryTemplate(string queryType);
/// <summary>
/// Get available query template types
/// </summary>
List<QueryTemplateInfo> GetAvailableQueryTemplates();
}
public class QueryTemplateInfo
{
public string Type { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}

View file

@ -0,0 +1,301 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Erp.Platform.DynamicData;
using Erp.Platform.Queries;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.Domain.Services;
namespace Erp.SqlQueryManager.Domain.Services;
public class SqlExecutorService : DomainService, ISqlExecutorService
{
private readonly IDataSourceManager _dataSourceManager;
private readonly IServiceProvider _serviceProvider;
public SqlExecutorService(
IDataSourceManager dataSourceManager,
IServiceProvider serviceProvider)
{
_dataSourceManager = dataSourceManager;
_serviceProvider = serviceProvider;
}
private async Task<IDynamicDataRepository> GetRepositoryAsync(string dataSourceCode)
{
// Get DataSource to determine database type
var dataSource = await _dataSourceManager.GetDataSourceAsync(
CurrentTenant.IsAvailable,
dataSourceCode);
if (dataSource == null)
{
throw new BusinessException("SqlQueryManager:DataSourceNotFound")
.WithData("DataSourceCode", dataSourceCode);
}
// Get appropriate repository based on database type
// For now, using MS SQL Server repository
var repository = _serviceProvider.GetKeyedService<IDynamicDataRepository>("Ms");
if (repository == null)
{
throw new BusinessException("SqlQueryManager:RepositoryNotFound")
.WithData("DatabaseType", "Ms");
}
return repository;
}
public async Task<SqlExecutionResult> ExecuteQueryAsync(
string sql,
string dataSourceCode,
Dictionary<string, object> parameters = null)
{
var stopwatch = Stopwatch.StartNew();
var result = new SqlExecutionResult();
try
{
var connectionString = await _dataSourceManager.GetConnectionStringAsync(
CurrentTenant.IsAvailable,
dataSourceCode);
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new BusinessException("SqlQueryManager:InvalidConnectionString")
.WithData("DataSourceCode", dataSourceCode);
}
var repository = await GetRepositoryAsync(dataSourceCode);
var data = await repository.QueryAsync(sql, connectionString, parameters);
stopwatch.Stop();
result.Success = true;
result.Data = data;
result.RowsAffected = data?.Count() ?? 0;
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
result.Message = $"Query executed successfully. Rows returned: {result.RowsAffected}";
}
catch (Exception ex)
{
stopwatch.Stop();
result.Success = false;
result.Message = $"Query execution failed: {ex.Message}";
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
result.Metadata["ErrorDetail"] = ex.ToString();
}
return result;
}
public async Task<SqlExecutionResult> ExecuteNonQueryAsync(
string sql,
string dataSourceCode,
Dictionary<string, object> parameters = null)
{
var stopwatch = Stopwatch.StartNew();
var result = new SqlExecutionResult();
try
{
var connectionString = await _dataSourceManager.GetConnectionStringAsync(
CurrentTenant.IsAvailable,
dataSourceCode);
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new BusinessException("SqlQueryManager:InvalidConnectionString")
.WithData("DataSourceCode", dataSourceCode);
}
var repository = await GetRepositoryAsync(dataSourceCode);
var rowsAffected = await repository.ExecuteAsync(sql, connectionString, parameters);
stopwatch.Stop();
result.Success = true;
result.RowsAffected = rowsAffected;
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
result.Message = $"Command executed successfully. Rows affected: {rowsAffected}";
}
catch (Exception ex)
{
stopwatch.Stop();
result.Success = false;
result.Message = $"Command execution failed: {ex.Message}";
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
result.Metadata["ErrorDetail"] = ex.ToString();
}
return result;
}
public async Task<SqlExecutionResult> ExecuteScalarAsync<T>(
string sql,
string dataSourceCode,
Dictionary<string, object> parameters = null)
{
var stopwatch = Stopwatch.StartNew();
var result = new SqlExecutionResult();
try
{
var connectionString = await _dataSourceManager.GetConnectionStringAsync(
CurrentTenant.IsAvailable,
dataSourceCode);
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new BusinessException("SqlQueryManager:InvalidConnectionString")
.WithData("DataSourceCode", dataSourceCode);
}
var repository = await GetRepositoryAsync(dataSourceCode);
var scalarValue = await repository.ExecuteScalarAsync<T>(sql, connectionString, parameters);
stopwatch.Stop();
result.Success = true;
result.Data = new[] { new { Value = scalarValue } };
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
result.Message = "Scalar query executed successfully";
result.Metadata["ScalarValue"] = scalarValue;
}
catch (Exception ex)
{
stopwatch.Stop();
result.Success = false;
result.Message = $"Scalar query execution failed: {ex.Message}";
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
result.Metadata["ErrorDetail"] = ex.ToString();
}
return result;
}
public async Task<SqlExecutionResult> DeployStoredProcedureAsync(
string procedureBody,
string dataSourceCode)
{
return await ExecuteNonQueryAsync(procedureBody, dataSourceCode);
}
public async Task<SqlExecutionResult> DeployViewAsync(
string viewDefinition,
string dataSourceCode)
{
return await ExecuteNonQueryAsync(viewDefinition, dataSourceCode);
}
public async Task<SqlExecutionResult> DeployFunctionAsync(
string functionBody,
string dataSourceCode)
{
return await ExecuteNonQueryAsync(functionBody, dataSourceCode);
}
public async Task<bool> CheckObjectExistsAsync(
string objectName,
string objectType,
string dataSourceCode,
string schemaName = "dbo")
{
try
{
var sql = $@"
SELECT COUNT(*)
FROM sys.objects o
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE s.name = @SchemaName
AND o.name = @ObjectName
AND o.type_desc = @ObjectType";
var parameters = new Dictionary<string, object>
{
{ "SchemaName", schemaName },
{ "ObjectName", objectName },
{ "ObjectType", objectType.ToUpperInvariant() }
};
var result = await ExecuteScalarAsync<int>(sql, dataSourceCode, parameters);
return result.Success && result.Metadata.ContainsKey("ScalarValue")
&& Convert.ToInt32(result.Metadata["ScalarValue"]) > 0;
}
catch
{
return false;
}
}
public async Task<SqlExecutionResult> DropObjectAsync(
string objectName,
string objectType,
string dataSourceCode,
string schemaName = "dbo")
{
var dropCommand = objectType.ToUpperInvariant() switch
{
"SQL_STORED_PROCEDURE" => $"DROP PROCEDURE IF EXISTS [{schemaName}].[{objectName}]",
"VIEW" => $"DROP VIEW IF EXISTS [{schemaName}].[{objectName}]",
"SQL_SCALAR_FUNCTION" => $"DROP FUNCTION IF EXISTS [{schemaName}].[{objectName}]",
"SQL_TABLE_VALUED_FUNCTION" => $"DROP FUNCTION IF EXISTS [{schemaName}].[{objectName}]",
"SQL_INLINE_TABLE_VALUED_FUNCTION" => $"DROP FUNCTION IF EXISTS [{schemaName}].[{objectName}]",
_ => throw new BusinessException("SqlQueryManager:UnsupportedObjectType")
.WithData("ObjectType", objectType)
};
return await ExecuteNonQueryAsync(dropCommand, dataSourceCode);
}
public Task<(bool IsValid, string ErrorMessage)> ValidateSqlAsync(string sql)
{
try
{
if (string.IsNullOrWhiteSpace(sql))
{
return Task.FromResult((false, "SQL query is empty"));
}
// Basic validation - check for dangerous keywords
var dangerousPatterns = new[]
{
@"\bDROP\s+DATABASE\b",
@"\bDROP\s+SCHEMA\b",
@"\bTRUNCATE\s+TABLE\b",
@"\bALTER\s+DATABASE\b",
@"\bSHUTDOWN\b",
@"\bxp_cmdshell\b"
};
foreach (var pattern in dangerousPatterns)
{
if (Regex.IsMatch(sql, pattern, RegexOptions.IgnoreCase))
{
return Task.FromResult((false, $"SQL contains potentially dangerous command: {pattern}"));
}
}
// Check for balanced parentheses
var openCount = sql.Count(c => c == '(');
var closeCount = sql.Count(c => c == ')');
if (openCount != closeCount)
{
return Task.FromResult((false, "Unbalanced parentheses in SQL"));
}
return Task.FromResult((true, string.Empty));
}
catch (Exception ex)
{
return Task.FromResult((false, $"Validation error: {ex.Message}"));
}
}
}

View file

@ -0,0 +1,395 @@
using System.Collections.Generic;
using System.Text;
using Erp.SqlQueryManager.Domain.Shared;
using Volo.Abp.DependencyInjection;
namespace Erp.SqlQueryManager.Domain.Services;
public class SqlTemplateProvider : ISqlTemplateProvider, ITransientDependency
{
public string GetStoredProcedureTemplate(string procedureName, string schemaName = "dbo")
{
return $@"-- =============================================
-- Author: <Author Name>
-- Create date: <Create Date>
-- Description: <Description>
-- =============================================
CREATE OR ALTER PROCEDURE [{schemaName}].[{procedureName}]
-- Add parameters here
@Parameter1 INT = NULL,
@Parameter2 NVARCHAR(100) = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT
@Parameter1 AS Parameter1,
@Parameter2 AS Parameter2
-- Example error handling
BEGIN TRY
-- Your logic here
END TRY
BEGIN CATCH
-- Error handling
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
DECLARE @ErrorSeverity INT = ERROR_SEVERITY();
DECLARE @ErrorState INT = ERROR_STATE();
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
END
GO";
}
public string GetViewTemplate(string viewName, string schemaName = "dbo", bool withSchemaBinding = false)
{
var schemaBindingClause = withSchemaBinding ? " WITH SCHEMABINDING" : "";
return $@"-- =============================================
-- Author: <Author Name>
-- Create date: <Create Date>
-- Description: <Description>
-- =============================================
CREATE OR ALTER VIEW [{schemaName}].[{viewName}]{schemaBindingClause}
AS
-- Define your SELECT statement here
SELECT
Column1,
Column2,
Column3
FROM
TableName
WHERE
-- Add your conditions
1 = 1
GO";
}
public string GetFunctionTemplate(string functionName, SqlFunctionType functionType, string schemaName = "dbo")
{
return functionType switch
{
SqlFunctionType.ScalarFunction => GetScalarFunctionTemplate(functionName, schemaName),
SqlFunctionType.TableValuedFunction => GetTableValuedFunctionTemplate(functionName, schemaName),
SqlFunctionType.InlineTableValuedFunction => GetInlineTableValuedFunctionTemplate(functionName, schemaName),
_ => GetScalarFunctionTemplate(functionName, schemaName)
};
}
private string GetScalarFunctionTemplate(string functionName, string schemaName)
{
return $@"-- =============================================
-- Author: <Author Name>
-- Create date: <Create Date>
-- Description: Scalar function that returns a single value
-- =============================================
CREATE OR ALTER FUNCTION [{schemaName}].[{functionName}]
(
-- Add parameters here
@Parameter1 INT,
@Parameter2 NVARCHAR(100)
)
RETURNS INT
AS
BEGIN
-- Declare the return variable here
DECLARE @Result INT;
-- Add your logic here
SELECT @Result = COUNT(*)
FROM YourTable
WHERE Column1 = @Parameter1;
-- Return the result
RETURN @Result;
END
GO";
}
private string GetTableValuedFunctionTemplate(string functionName, string schemaName)
{
return $@"-- =============================================
-- Author: <Author Name>
-- Create date: <Create Date>
-- Description: Multi-statement table-valued function
-- =============================================
CREATE OR ALTER FUNCTION [{schemaName}].[{functionName}]
(
-- Add parameters here
@Parameter1 INT,
@Parameter2 NVARCHAR(100)
)
RETURNS @ResultTable TABLE
(
-- Define the structure of the result table
Id INT,
Name NVARCHAR(100),
Value DECIMAL(18,2)
)
AS
BEGIN
-- Fill the table variable with data
INSERT INTO @ResultTable (Id, Name, Value)
SELECT
Id,
Name,
Value
FROM
YourTable
WHERE
Column1 = @Parameter1;
-- Return
RETURN;
END
GO";
}
private string GetInlineTableValuedFunctionTemplate(string functionName, string schemaName)
{
return $@"-- =============================================
-- Author: <Author Name>
-- Create date: <Create Date>
-- Description: Inline table-valued function
-- =============================================
CREATE OR ALTER FUNCTION [{schemaName}].[{functionName}]
(
-- Add parameters here
@Parameter1 INT,
@Parameter2 NVARCHAR(100)
)
RETURNS TABLE
AS
RETURN
(
-- Add your SELECT statement here
SELECT
Id,
Name,
Value,
CreatedDate
FROM
YourTable
WHERE
Column1 = @Parameter1
AND Column2 LIKE '%' + @Parameter2 + '%'
)
GO";
}
public string GetQueryTemplate(string queryType)
{
return queryType?.ToUpperInvariant() switch
{
"SELECT" => GetSelectTemplate(),
"INSERT" => GetInsertTemplate(),
"UPDATE" => GetUpdateTemplate(),
"DELETE" => GetDeleteTemplate(),
"JOIN" => GetJoinTemplate(),
"CTE" => GetCteTemplate(),
"PIVOT" => GetPivotTemplate(),
"TRANSACTION" => GetTransactionTemplate(),
_ => GetSelectTemplate()
};
}
private string GetSelectTemplate()
{
return @"-- Basic SELECT query
SELECT
Column1,
Column2,
Column3
FROM
TableName
WHERE
-- Add your conditions
Column1 = 'value'
AND IsActive = 1
ORDER BY
Column1 ASC;";
}
private string GetInsertTemplate()
{
return @"-- INSERT statement
INSERT INTO TableName
(
Column1,
Column2,
Column3,
CreatedDate
)
VALUES
(
'Value1',
'Value2',
123,
GETDATE()
);
-- Or with SELECT
INSERT INTO TableName (Column1, Column2)
SELECT
Column1,
Column2
FROM
SourceTable
WHERE
Condition = 1;";
}
private string GetUpdateTemplate()
{
return @"-- UPDATE statement
UPDATE TableName
SET
Column1 = 'NewValue',
Column2 = 'NewValue2',
UpdatedDate = GETDATE()
WHERE
Id = 123
AND IsActive = 1;";
}
private string GetDeleteTemplate()
{
return @"-- DELETE statement
DELETE FROM TableName
WHERE
Id = 123
AND IsActive = 0;
-- Soft delete pattern
UPDATE TableName
SET
IsDeleted = 1,
DeletedDate = GETDATE(),
DeletedBy = 'UserName'
WHERE
Id = 123;";
}
private string GetJoinTemplate()
{
return @"-- JOIN query example
SELECT
t1.Column1,
t1.Column2,
t2.Column3,
t3.Column4
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.Id = t2.Table1Id
LEFT JOIN Table3 t3 ON t2.Id = t3.Table2Id
WHERE
t1.IsActive = 1
AND t2.Status = 'Active'
ORDER BY
t1.Column1;";
}
private string GetCteTemplate()
{
return @"-- Common Table Expression (CTE) example
WITH CTE_Name AS
(
SELECT
Column1,
Column2,
COUNT(*) as RecordCount
FROM
TableName
WHERE
IsActive = 1
GROUP BY
Column1, Column2
)
SELECT
*
FROM
CTE_Name
WHERE
RecordCount > 5
ORDER BY
RecordCount DESC;";
}
private string GetPivotTemplate()
{
return @"-- PIVOT example
SELECT
*
FROM
(
SELECT
Category,
Year,
Amount
FROM
Sales
) AS SourceTable
PIVOT
(
SUM(Amount)
FOR Year IN ([2021], [2022], [2023], [2024])
) AS PivotTable
ORDER BY
Category;";
}
private string GetTransactionTemplate()
{
return @"-- Transaction example
BEGIN TRANSACTION;
BEGIN TRY
-- Your SQL statements here
UPDATE Table1
SET Column1 = 'Value'
WHERE Id = 1;
INSERT INTO Table2 (Column1, Column2)
VALUES ('Value1', 'Value2');
DELETE FROM Table3
WHERE Id = 123;
-- Commit if all successful
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Rollback on error
ROLLBACK TRANSACTION;
-- Return error information
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH;";
}
public List<QueryTemplateInfo> GetAvailableQueryTemplates()
{
return new List<QueryTemplateInfo>
{
new() { Type = "SELECT", Name = "Basic Select", Description = "Simple SELECT query with WHERE and ORDER BY" },
new() { Type = "INSERT", Name = "Insert Data", Description = "INSERT statement with VALUES or SELECT" },
new() { Type = "UPDATE", Name = "Update Data", Description = "UPDATE statement with conditions" },
new() { Type = "DELETE", Name = "Delete Data", Description = "DELETE statement with soft delete example" },
new() { Type = "JOIN", Name = "Join Tables", Description = "Query with INNER and LEFT JOINs" },
new() { Type = "CTE", Name = "Common Table Expression", Description = "CTE (WITH clause) example" },
new() { Type = "PIVOT", Name = "Pivot Table", Description = "PIVOT query for data transformation" },
new() { Type = "TRANSACTION", Name = "Transaction", Description = "Transaction with error handling" }
};
}
}

View file

@ -0,0 +1,19 @@
namespace Erp.SqlQueryManager;
public static class Prefix
{
public static string MenuPrefix { get; set; } = "Sqm";
public static string HostPrefix { get; set; } = "T";
public static string? DbSchema { get; set; } = null;
public const string ConnectionStringName = "SqlQueryManager";
}
public static class TablePrefix
{
public static string ByName(string tableName)
{
return $"{Prefix.MenuPrefix}_{Prefix.HostPrefix}_{tableName}";
}
}

View file

@ -0,0 +1,17 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
namespace Erp.SqlQueryManager;
[DependsOn(
typeof(AbpDddDomainModule),
typeof(SqlQueryManagerDomainSharedModule)
)]
public class SqlQueryManagerDomainModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// Domain services configuration can be added here
}
}

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\common.props" />
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Erp.SqlQueryManager</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="9.0.2" />
<ProjectReference Include="..\Erp.SqlQueryManager.Domain\Erp.SqlQueryManager.Domain.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,27 @@
using Erp.SqlQueryManager.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace Erp.SqlQueryManager.EntityFrameworkCore;
[ConnectionStringName("Default")]
public class SqlQueryManagerDbContext : AbpDbContext<SqlQueryManagerDbContext>
{
public DbSet<SqlQuery> SqlQueries { get; set; }
public DbSet<SqlStoredProcedure> SqlStoredProcedures { get; set; }
public DbSet<SqlView> SqlViews { get; set; }
public DbSet<SqlFunction> SqlFunctions { get; set; }
public SqlQueryManagerDbContext(DbContextOptions<SqlQueryManagerDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureSqlQueryManager();
}
}

View file

@ -0,0 +1,104 @@
using Erp.SqlQueryManager.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace Erp.SqlQueryManager.EntityFrameworkCore;
public static class SqlQueryManagerDbContextModelCreatingExtensions
{
public static void ConfigureSqlQueryManager(this ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
// SqlQuery
builder.Entity<SqlQuery>(b =>
{
b.ToTable(TablePrefix.ByName(nameof(SqlQuery)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Code).IsRequired().HasMaxLength(128);
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
b.Property(x => x.Description).HasMaxLength(1000);
b.Property(x => x.QueryText).IsRequired();
b.Property(x => x.DataSourceCode).IsRequired().HasMaxLength(128);
b.Property(x => x.Status).IsRequired();
b.Property(x => x.Category).HasMaxLength(128);
b.Property(x => x.Tags).HasMaxLength(500);
b.Property(x => x.Parameters).HasMaxLength(4000);
b.HasIndex(x => x.Code);
b.HasIndex(x => x.DataSourceCode);
b.HasIndex(x => x.Status);
b.HasIndex(x => x.Category);
});
// SqlStoredProcedure
builder.Entity<SqlStoredProcedure>(b =>
{
b.ToTable(TablePrefix.ByName(nameof(SqlStoredProcedure)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.ProcedureName).IsRequired().HasMaxLength(128);
b.Property(x => x.SchemaName).IsRequired().HasMaxLength(128);
b.Property(x => x.DisplayName).IsRequired().HasMaxLength(256);
b.Property(x => x.Description).HasMaxLength(1000);
b.Property(x => x.ProcedureBody).IsRequired();
b.Property(x => x.DataSourceCode).IsRequired().HasMaxLength(128);
b.Property(x => x.Status).IsRequired();
b.Property(x => x.Category).HasMaxLength(128);
b.Property(x => x.Parameters).HasMaxLength(4000);
b.HasIndex(x => new { x.SchemaName, x.ProcedureName });
b.HasIndex(x => x.DataSourceCode);
b.HasIndex(x => x.Status);
b.HasIndex(x => x.IsDeployed);
});
// SqlView
builder.Entity<SqlView>(b =>
{
b.ToTable(TablePrefix.ByName(nameof(SqlView)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.ViewName).IsRequired().HasMaxLength(128);
b.Property(x => x.SchemaName).IsRequired().HasMaxLength(128);
b.Property(x => x.DisplayName).IsRequired().HasMaxLength(256);
b.Property(x => x.Description).HasMaxLength(1000);
b.Property(x => x.ViewDefinition).IsRequired();
b.Property(x => x.DataSourceCode).IsRequired().HasMaxLength(128);
b.Property(x => x.Status).IsRequired();
b.Property(x => x.Category).HasMaxLength(128);
b.HasIndex(x => new { x.SchemaName, x.ViewName });
b.HasIndex(x => x.DataSourceCode);
b.HasIndex(x => x.Status);
b.HasIndex(x => x.IsDeployed);
});
// SqlFunction
builder.Entity<SqlFunction>(b =>
{
b.ToTable(TablePrefix.ByName(nameof(SqlFunction)), Prefix.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.FunctionName).IsRequired().HasMaxLength(128);
b.Property(x => x.SchemaName).IsRequired().HasMaxLength(128);
b.Property(x => x.DisplayName).IsRequired().HasMaxLength(256);
b.Property(x => x.Description).HasMaxLength(1000);
b.Property(x => x.FunctionType).IsRequired();
b.Property(x => x.FunctionBody).IsRequired();
b.Property(x => x.ReturnType).IsRequired().HasMaxLength(256);
b.Property(x => x.DataSourceCode).IsRequired().HasMaxLength(128);
b.Property(x => x.Status).IsRequired();
b.Property(x => x.Category).HasMaxLength(128);
b.Property(x => x.Parameters).HasMaxLength(4000);
b.HasIndex(x => new { x.SchemaName, x.FunctionName });
b.HasIndex(x => x.DataSourceCode);
b.HasIndex(x => x.Status);
b.HasIndex(x => x.FunctionType);
b.HasIndex(x => x.IsDeployed);
});
}
}

View file

@ -0,0 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
namespace Erp.SqlQueryManager.EntityFrameworkCore;
[DependsOn(
typeof(SqlQueryManagerDomainModule),
typeof(AbpEntityFrameworkCoreModule)
)]
public class SqlQueryManagerEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<SqlQueryManagerDbContext>(options =>
{
options.AddDefaultRepositories(includeAllEntities: true);
});
}
}

View file

@ -0,0 +1,24 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>0.1.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AbpProjectType>module</AbpProjectType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.5.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
<PropertyGroup>
<NoWarn>$(NoWarn);0436</NoWarn>
</PropertyGroup>
</Target>
</Project>

View file

@ -26,6 +26,7 @@ using System.Text.Json;
using static Erp.Platform.PlatformConsts;
using static Erp.Settings.SettingsConsts;
using Erp.Platform.Enums;
using Erp.SqlQueryManager.EntityFrameworkCore;
namespace Erp.Platform.EntityFrameworkCore;
@ -333,6 +334,7 @@ public class PlatformDbContext :
builder.ConfigureSettings();
builder.ConfigureMailQueue();
builder.ConfigureNotification();
builder.ConfigureSqlQueryManager();
//Saas
builder.Entity<AiBot>(b =>

View file

@ -2,6 +2,7 @@
using Erp.Languages.EntityFrameworkCore;
using Erp.Notifications.EntityFrameworkCore;
using Erp.Settings.EntityFrameworkCore;
using Erp.SqlQueryManager.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
@ -34,7 +35,8 @@ namespace Erp.Platform.EntityFrameworkCore;
typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(LanguagesEntityFrameworkCoreModule),
typeof(SettingsEntityFrameworkCoreModule),
typeof(NotificationEntityFrameworkCoreModule)
typeof(NotificationEntityFrameworkCoreModule),
typeof(SqlQueryManagerEntityFrameworkCoreModule)
)]
public class PlatformEntityFrameworkCoreModule : AbpModule
{

View file

@ -28,6 +28,7 @@
<ProjectReference Include="..\..\modules\Erp.Languages\Erp.Languages.EntityFrameworkCore\Erp.Languages.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.Notifications\Erp.Notifications.EntityFrameworkCore\Erp.Notifications.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.Settings\Erp.Settings.EntityFrameworkCore\Erp.Settings.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\Erp.SqlQueryManager\Erp.SqlQueryManager.EntityFrameworkCore\Erp.SqlQueryManager.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\Erp.Platform.Domain\Erp.Platform.Domain.csproj" />
<PackageReference Include="Volo.Abp.Dapper" Version="9.0.2" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="9.0.2" />

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Erp.Platform.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20251204192908_Initial")]
[Migration("20251205085044_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -16250,6 +16250,409 @@ namespace Erp.Platform.Migrations
b.ToTable("Plat_H_SettingDefinition", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlFunction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("FunctionBody")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FunctionName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("FunctionType")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsDeployed")
.HasColumnType("bit");
b.Property<DateTime?>("LastDeployedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Parameters")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<string>("ReturnType")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("SchemaName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("DataSourceCode");
b.HasIndex("FunctionType");
b.HasIndex("IsDeployed");
b.HasIndex("Status");
b.HasIndex("SchemaName", "FunctionName");
b.ToTable("Sqm_T_SqlFunction", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlQuery", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<int>("ExecutionCount")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsModifyingData")
.HasColumnType("bit");
b.Property<DateTime?>("LastExecutedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Parameters")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<string>("QueryText")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("Tags")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("Category");
b.HasIndex("Code");
b.HasIndex("DataSourceCode");
b.HasIndex("Status");
b.ToTable("Sqm_T_SqlQuery", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlStoredProcedure", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsDeployed")
.HasColumnType("bit");
b.Property<DateTime?>("LastDeployedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Parameters")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<string>("ProcedureBody")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ProcedureName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("SchemaName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("DataSourceCode");
b.HasIndex("IsDeployed");
b.HasIndex("Status");
b.HasIndex("SchemaName", "ProcedureName");
b.ToTable("Sqm_T_SqlStoredProcedure", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlView", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsDeployed")
.HasColumnType("bit");
b.Property<DateTime?>("LastDeployedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("SchemaName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("ViewDefinition")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ViewName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<bool>("WithSchemaBinding")
.HasColumnType("bit");
b.HasKey("Id");
b.HasIndex("DataSourceCode");
b.HasIndex("IsDeployed");
b.HasIndex("Status");
b.HasIndex("SchemaName", "ViewName");
b.ToTable("Sqm_T_SqlView", (string)null);
});
modelBuilder.Entity("MaterialUom", b =>
{
b.Property<Guid>("AlternativeUomsId")

View file

@ -2864,6 +2864,129 @@ namespace Erp.Platform.Migrations
table.PrimaryKey("PK_Scp_T_SupplyType", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Sqm_T_SqlFunction",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
FunctionName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
SchemaName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
Description = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: true),
FunctionType = table.Column<int>(type: "int", nullable: false),
FunctionBody = table.Column<string>(type: "nvarchar(max)", nullable: false),
ReturnType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
DataSourceCode = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
Category = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
IsDeployed = table.Column<bool>(type: "bit", nullable: false),
LastDeployedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
Parameters = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Sqm_T_SqlFunction", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Sqm_T_SqlQuery",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
Code = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
Description = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: true),
QueryText = table.Column<string>(type: "nvarchar(max)", nullable: false),
DataSourceCode = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
Category = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
Tags = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
LastExecutedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
ExecutionCount = table.Column<int>(type: "int", nullable: false),
IsModifyingData = table.Column<bool>(type: "bit", nullable: false),
Parameters = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Sqm_T_SqlQuery", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Sqm_T_SqlStoredProcedure",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
ProcedureName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
SchemaName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
Description = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: true),
ProcedureBody = table.Column<string>(type: "nvarchar(max)", nullable: false),
DataSourceCode = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
Category = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
IsDeployed = table.Column<bool>(type: "bit", nullable: false),
LastDeployedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
Parameters = table.Column<string>(type: "nvarchar(4000)", maxLength: 4000, nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Sqm_T_SqlStoredProcedure", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Sqm_T_SqlView",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
ViewName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
SchemaName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
DisplayName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
Description = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: true),
ViewDefinition = table.Column<string>(type: "nvarchar(max)", nullable: false),
DataSourceCode = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Status = table.Column<int>(type: "int", nullable: false),
Category = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
IsDeployed = table.Column<bool>(type: "bit", nullable: false),
LastDeployedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
WithSchemaBinding = table.Column<bool>(type: "bit", nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Sqm_T_SqlView", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Str_T_Inventory",
columns: table => new
@ -9041,6 +9164,91 @@ namespace Erp.Platform.Migrations
table: "Scp_T_RequestItem",
column: "RequestId");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlFunction_DataSourceCode",
table: "Sqm_T_SqlFunction",
column: "DataSourceCode");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlFunction_FunctionType",
table: "Sqm_T_SqlFunction",
column: "FunctionType");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlFunction_IsDeployed",
table: "Sqm_T_SqlFunction",
column: "IsDeployed");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlFunction_SchemaName_FunctionName",
table: "Sqm_T_SqlFunction",
columns: new[] { "SchemaName", "FunctionName" });
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlFunction_Status",
table: "Sqm_T_SqlFunction",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlQuery_Category",
table: "Sqm_T_SqlQuery",
column: "Category");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlQuery_Code",
table: "Sqm_T_SqlQuery",
column: "Code");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlQuery_DataSourceCode",
table: "Sqm_T_SqlQuery",
column: "DataSourceCode");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlQuery_Status",
table: "Sqm_T_SqlQuery",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlStoredProcedure_DataSourceCode",
table: "Sqm_T_SqlStoredProcedure",
column: "DataSourceCode");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlStoredProcedure_IsDeployed",
table: "Sqm_T_SqlStoredProcedure",
column: "IsDeployed");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlStoredProcedure_SchemaName_ProcedureName",
table: "Sqm_T_SqlStoredProcedure",
columns: new[] { "SchemaName", "ProcedureName" });
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlStoredProcedure_Status",
table: "Sqm_T_SqlStoredProcedure",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlView_DataSourceCode",
table: "Sqm_T_SqlView",
column: "DataSourceCode");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlView_IsDeployed",
table: "Sqm_T_SqlView",
column: "IsDeployed");
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlView_SchemaName_ViewName",
table: "Sqm_T_SqlView",
columns: new[] { "SchemaName", "ViewName" });
migrationBuilder.CreateIndex(
name: "IX_Sqm_T_SqlView_Status",
table: "Sqm_T_SqlView",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_Str_T_Location_LocationTypeId",
table: "Str_T_Location",
@ -9632,6 +9840,18 @@ namespace Erp.Platform.Migrations
migrationBuilder.DropTable(
name: "Scp_T_RequestItem");
migrationBuilder.DropTable(
name: "Sqm_T_SqlFunction");
migrationBuilder.DropTable(
name: "Sqm_T_SqlQuery");
migrationBuilder.DropTable(
name: "Sqm_T_SqlStoredProcedure");
migrationBuilder.DropTable(
name: "Sqm_T_SqlView");
migrationBuilder.DropTable(
name: "Str_T_Inventory");

View file

@ -16247,6 +16247,409 @@ namespace Erp.Platform.Migrations
b.ToTable("Plat_H_SettingDefinition", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlFunction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("FunctionBody")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FunctionName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("FunctionType")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsDeployed")
.HasColumnType("bit");
b.Property<DateTime?>("LastDeployedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Parameters")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<string>("ReturnType")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("SchemaName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("DataSourceCode");
b.HasIndex("FunctionType");
b.HasIndex("IsDeployed");
b.HasIndex("Status");
b.HasIndex("SchemaName", "FunctionName");
b.ToTable("Sqm_T_SqlFunction", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlQuery", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<int>("ExecutionCount")
.HasColumnType("int");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsModifyingData")
.HasColumnType("bit");
b.Property<DateTime?>("LastExecutedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Parameters")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<string>("QueryText")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<string>("Tags")
.HasMaxLength(500)
.HasColumnType("nvarchar(500)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("Category");
b.HasIndex("Code");
b.HasIndex("DataSourceCode");
b.HasIndex("Status");
b.ToTable("Sqm_T_SqlQuery", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlStoredProcedure", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsDeployed")
.HasColumnType("bit");
b.Property<DateTime?>("LastDeployedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Parameters")
.HasMaxLength(4000)
.HasColumnType("nvarchar(4000)");
b.Property<string>("ProcedureBody")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ProcedureName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("SchemaName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("DataSourceCode");
b.HasIndex("IsDeployed");
b.HasIndex("Status");
b.HasIndex("SchemaName", "ProcedureName");
b.ToTable("Sqm_T_SqlStoredProcedure", (string)null);
});
modelBuilder.Entity("Erp.SqlQueryManager.Domain.Entities.SqlView", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Category")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DataSourceCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.HasMaxLength(1000)
.HasColumnType("nvarchar(1000)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsDeployed")
.HasColumnType("bit");
b.Property<DateTime?>("LastDeployedAt")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("SchemaName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("ViewDefinition")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ViewName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<bool>("WithSchemaBinding")
.HasColumnType("bit");
b.HasKey("Id");
b.HasIndex("DataSourceCode");
b.HasIndex("IsDeployed");
b.HasIndex("Status");
b.HasIndex("SchemaName", "ViewName");
b.ToTable("Sqm_T_SqlView", (string)null);
});
modelBuilder.Entity("MaterialUom", b =>
{
b.Property<Guid>("AlternativeUomsId")

View file

@ -6,7 +6,6 @@
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Erp.Platform</RootNamespace>
<PreserveCompilationReferences>true</PreserveCompilationReferences>
<UserSecretsId>Erp.Platform-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId>
</PropertyGroup>
<ItemGroup>
@ -32,6 +31,7 @@
<ProjectReference Include="..\Erp.Platform.Application\Erp.Platform.Application.csproj" />
<ProjectReference Include="..\Erp.Platform.EntityFrameworkCore\Erp.Platform.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\Erp.Platform.HttpApi\Erp.Platform.HttpApi.csproj" />
<ProjectReference Include="..\..\modules\Erp.SqlQueryManager\Erp.SqlQueryManager.Application\Erp.SqlQueryManager.Application.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -9,6 +9,7 @@ using Erp.MailQueue;
using Erp.Notifications.Application;
using Erp.Platform.Classrooms;
using Erp.Platform.EntityFrameworkCore;
using Erp.SqlQueryManager;
using Erp.Platform.Extensions;
using Erp.Platform.FileManagement;
using Erp.Platform.Identity;
@ -51,7 +52,6 @@ using Volo.Abp.Swashbuckle;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
using Erp.Platform.DynamicServices;
using Erp.Platform.DeveloperKit;
using static Erp.Platform.PlatformConsts;
using static Erp.Settings.SettingsConsts;
@ -67,7 +67,8 @@ namespace Erp.Platform;
typeof(AbpAccountWebOpenIddictModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpSwashbuckleModule),
typeof(AbpBackgroundWorkersHangfireModule)
typeof(AbpBackgroundWorkersHangfireModule),
typeof(SqlQueryManagerApplicationModule)
)]
public class PlatformHttpApiHostModule : AbpModule
{
@ -204,6 +205,7 @@ public class PlatformHttpApiHostModule : AbpModule
options.ConventionalControllers.Create(typeof(SettingsApplicationModule).Assembly);
options.ConventionalControllers.Create(typeof(ErpMailQueueModule).Assembly);
options.ConventionalControllers.Create(typeof(NotificationApplicationModule).Assembly);
options.ConventionalControllers.Create(typeof(SqlQueryManagerApplicationModule).Assembly);
options.ChangeControllerModelApiExplorerGroupName = false;
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(PlatformUpdateProfileDto));
options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(UploadFileDto));