Database migration, repository, controller and service
This commit is contained in:
1 parent
07e4e6b381
commit
4fb8768807
17 files changed
+368
-44
No files matched your search
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace PaperlessAI.Bodies;
|
|
||||||
|
|
||||||
public class NewDocumentBody
|
|
||||||
{
|
|
||||||
[JsonProperty("document_id")]
|
|
||||||
public int DocumentId { get; set; }
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PaperlessAI.Bodies;
|
||||||
|
|
||||||
|
public class NewPaperlessDocumentBody
|
||||||
|
{
|
||||||
|
[JsonProperty("document_id")]
|
||||||
|
public long DocumentId { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return JsonConvert.SerializeObject(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PaperlessAI.Models;
|
||||||
|
|
||||||
namespace PaperlessAI.Context;
|
namespace PaperlessAI.Context;
|
||||||
|
|
||||||
@@ -19,6 +19,13 @@ public class MyDbContext : DbContext
|
|||||||
modelBuilder
|
modelBuilder
|
||||||
.UseCollation("utf8mb4_uca1400_ai_ci")
|
.UseCollation("utf8mb4_uca1400_ai_ci")
|
||||||
.HasCharSet("utf8mb4");
|
.HasCharSet("utf8mb4");
|
||||||
|
|
||||||
|
modelBuilder
|
||||||
|
.Entity<PaperlessDocument>()
|
||||||
|
.HasIndex(x => x.DocumentId)
|
||||||
|
.IsUnique();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DbSet<PaperlessDocument> PaperlessDocuments { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using PaperlessAI.Bodies;
|
|
||||||
|
|
||||||
namespace PaperlessAI.Controllers
|
|
||||||
{
|
|
||||||
[Route("[controller]")]
|
|
||||||
[ApiController]
|
|
||||||
public class DocumentController : ControllerBase
|
|
||||||
{
|
|
||||||
[HttpPost]
|
|
||||||
public ActionResult AddNewDocument([FromBody]NewDocumentBody newDocument)
|
|
||||||
{
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using PaperlessAI.Bodies;
|
||||||
|
using PaperlessAI.Services;
|
||||||
|
|
||||||
|
namespace PaperlessAI.Controllers
|
||||||
|
{
|
||||||
|
[Route("Document")]
|
||||||
|
[ApiController]
|
||||||
|
public class PaperlessDocumentController(PaperlessDocumentService documentService, ILogger<PaperlessDocumentController> logger) : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult> AddNewDocument([FromBody]NewPaperlessDocumentBody newPaperlessDocumentBody)
|
||||||
|
{
|
||||||
|
logger.LogDebug($"AddNewDocument called with body: {newPaperlessDocumentBody}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(await documentService.Exists(newPaperlessDocumentBody.DocumentId))
|
||||||
|
{
|
||||||
|
logger.LogWarning($"Document {newPaperlessDocumentBody.DocumentId} already exists.");
|
||||||
|
return Conflict();
|
||||||
|
}
|
||||||
|
|
||||||
|
await documentService.Create(newPaperlessDocumentBody.DocumentId);
|
||||||
|
logger.LogWarning($"Document {newPaperlessDocumentBody.DocumentId} created.");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.LogError(e.ToString());
|
||||||
|
return StatusCode(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogDebug($"AddNewDocument Ok!");
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace PaperlessAI.Enums;
|
||||||
|
|
||||||
|
public enum EOperationState
|
||||||
|
{
|
||||||
|
Created = 0,
|
||||||
|
Queued = 1,
|
||||||
|
Started = 2,
|
||||||
|
Success = 3,
|
||||||
|
Failed = 4
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace PaperlessAI.Interfaces;
|
||||||
|
|
||||||
|
public interface IRepository<T>
|
||||||
|
{
|
||||||
|
Task Add(T model, bool persist = true);
|
||||||
|
Task Remove(T model, bool persist = true);
|
||||||
|
Task Update(T model, bool persist = true);
|
||||||
|
Task<T?> Get(long id);
|
||||||
|
Task<List<T>> GetAll();
|
||||||
|
|
||||||
|
}
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PaperlessAI.Context;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PaperlessAI.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(MyDbContext))]
|
||||||
|
[Migration("20261009132858_Init")]
|
||||||
|
partial class Init
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.UseCollation("utf8mb4_uca1400_ai_ci")
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.12")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
MySqlModelBuilderExtensions.HasCharSet(modelBuilder, "utf8mb4");
|
||||||
|
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("PaperlessAI.Models.PaperlessDocument", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<long>("DocumentId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("DocumentState")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("ModifiedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DocumentId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("PaperlessDocuments");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PaperlessAI.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Init : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterDatabase()
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "PaperlessDocuments",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
DocumentId = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
DocumentState = table.Column<int>(type: "int", nullable: false),
|
||||||
|
CreatedAt = table.Column<DateTimeOffset>(type: "datetime(6)", nullable: false),
|
||||||
|
ModifiedAt = table.Column<DateTimeOffset>(type: "datetime(6)", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_PaperlessDocuments", x => x.Id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4")
|
||||||
|
.Annotation("Relational:Collation", "utf8mb4_uca1400_ai_ci");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PaperlessDocuments_DocumentId",
|
||||||
|
table: "PaperlessDocuments",
|
||||||
|
column: "DocumentId",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "PaperlessDocuments");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PaperlessAI.Context;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace PaperlessAI.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(MyDbContext))]
|
||||||
|
partial class MyDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.UseCollation("utf8mb4_uca1400_ai_ci")
|
||||||
|
.HasAnnotation("ProductVersion", "10.0.12")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
MySqlModelBuilderExtensions.HasCharSet(modelBuilder, "utf8mb4");
|
||||||
|
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("PaperlessAI.Models.PaperlessDocument", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<long>("DocumentId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("DocumentState")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("ModifiedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DocumentId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("PaperlessDocuments");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using PaperlessAI.Enums;
|
||||||
|
|
||||||
|
namespace PaperlessAI.Models;
|
||||||
|
|
||||||
|
public class PaperlessDocument
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public long DocumentId { get; set; }
|
||||||
|
public EOperationState DocumentState { get; set; } = EOperationState.Created;
|
||||||
|
public DateTimeOffset CreatedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
public DateTimeOffset ModifiedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
public PaperlessDocument(long documentId)
|
||||||
|
{
|
||||||
|
DocumentId = documentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PaperlessDocument Create(long documentId)
|
||||||
|
{
|
||||||
|
var paperlessDocument = new PaperlessDocument(documentId);
|
||||||
|
return paperlessDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-1
@@ -11,7 +11,9 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.12" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.12" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0" />
|
<PackageReference Include="Microting.EntityFrameworkCore.MySql" Version="10.0.12" />
|
||||||
|
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
+27
-6
@@ -1,28 +1,49 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using PaperlessAI.Context;
|
using PaperlessAI.Context;
|
||||||
|
using PaperlessAI.Repositories;
|
||||||
|
using PaperlessAI.Services;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// Add services to the container.
|
// Services
|
||||||
|
builder.Services.AddScoped<PaperlessDocumentService>();
|
||||||
|
|
||||||
|
// Repositories
|
||||||
|
builder.Services.AddScoped<PaperlessDocumentRepository>();
|
||||||
|
|
||||||
|
// Other
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
|
// Database
|
||||||
builder.Services.AddDbContextPool<MyDbContext>(options =>
|
builder.Services.AddDbContextPool<MyDbContext>(options =>
|
||||||
{
|
{
|
||||||
options.UseMySql(
|
options.UseMySql(
|
||||||
builder.Configuration.GetConnectionString("MariaDbConnectionString"),
|
builder.Configuration.GetConnectionString("MariaDbConnectionString"),
|
||||||
ServerVersion.Parse("12.0.2-mariadb")
|
ServerVersion.Parse("12.0.2-mariadb")
|
||||||
);
|
)
|
||||||
|
.LogTo(Console.WriteLine, LogLevel.Information)
|
||||||
|
.EnableSensitiveDataLogging()
|
||||||
|
.EnableDetailedErrors();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
Log.Logger = new LoggerConfiguration()
|
||||||
|
.MinimumLevel.Debug()
|
||||||
|
.WriteTo.Console()
|
||||||
|
.WriteTo.File(
|
||||||
|
Path.Combine(AppContext.BaseDirectory, "logs", "log-.txt"),
|
||||||
|
rollingInterval: RollingInterval.Day,
|
||||||
|
retainedFileCountLimit: 30)
|
||||||
|
.CreateLogger();
|
||||||
|
|
||||||
|
builder.Host.UseSerilog();
|
||||||
|
|
||||||
|
// App
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -10,14 +10,5 @@
|
|||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"https": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": false,
|
|
||||||
"applicationUrl": "https://localhost:7245;http://localhost:5276",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PaperlessAI.Context;
|
||||||
|
using PaperlessAI.Interfaces;
|
||||||
|
using PaperlessAI.Models;
|
||||||
|
|
||||||
|
namespace PaperlessAI.Repositories;
|
||||||
|
|
||||||
|
public class PaperlessDocumentRepository(MyDbContext context) : IRepository<PaperlessDocument>
|
||||||
|
{
|
||||||
|
public async Task Add(PaperlessDocument model, bool persist = true)
|
||||||
|
{
|
||||||
|
await context.PaperlessDocuments.AddAsync(model);
|
||||||
|
await SaveOnPersist(persist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Remove(PaperlessDocument model, bool persist = true)
|
||||||
|
{
|
||||||
|
context.PaperlessDocuments.Remove(model);
|
||||||
|
await SaveOnPersist(persist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Update(PaperlessDocument model, bool persist = true)
|
||||||
|
{
|
||||||
|
context.PaperlessDocuments.Update(model);
|
||||||
|
await SaveOnPersist(persist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaperlessDocument?> Get(long id) => await context.PaperlessDocuments.Where(x => x.DocumentId == id).FirstOrDefaultAsync();
|
||||||
|
public async Task<List<PaperlessDocument>> GetAll() => await context.PaperlessDocuments.ToListAsync();
|
||||||
|
|
||||||
|
public async Task SaveOnPersist(bool persist)
|
||||||
|
{
|
||||||
|
if(persist)
|
||||||
|
{
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using PaperlessAI.Models;
|
||||||
|
using PaperlessAI.Repositories;
|
||||||
|
|
||||||
|
namespace PaperlessAI.Services;
|
||||||
|
|
||||||
|
public class PaperlessDocumentService(PaperlessDocumentRepository docRepo)
|
||||||
|
{
|
||||||
|
public async Task<bool> Exists(long documentId)
|
||||||
|
{
|
||||||
|
if(documentId < 0 || documentId > long.MaxValue)
|
||||||
|
throw new Exception($"Value \"{documentId}\" must be in Range between 0 - {long.MaxValue}!");
|
||||||
|
|
||||||
|
return await docRepo.Get(documentId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaperlessDocument> Create(long documentId)
|
||||||
|
{
|
||||||
|
var doc = PaperlessDocument.Create(documentId);
|
||||||
|
await docRepo.Add(doc);
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user