confighantering. connection t postgres. test av import

This commit is contained in:
florpan 2025-09-06 16:53:23 +02:00
parent 1744a5b7de
commit 8c54a120d1
9 changed files with 341 additions and 22 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ Server/.vs
Server/bin
Server/obj
Server/Bibblan.csproj.user
Server/appsettings.user.json

View File

@ -1 +1,8 @@
@import "../../node_modules/bootstrap/scss/bootstrap.scss";
.book-card {
.card-img-top {
padding: 1rem;
aspect-ratio: 3 / 4;
}
}

View File

@ -16,6 +16,15 @@
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<Content Update="appsettings.user.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -3,12 +3,12 @@ using Bibblan.ViewModels;
using Microsoft.Extensions.Options;
namespace Bibblan.Business.Services
{
{
public class CalibreService
{
private readonly BibblanOptions _options;
CalibreContext _context;
public CalibreService(CalibreContext context, IOptions<BibblanOptions> options)
SqliteCalibreContext _context;
public CalibreService(SqliteCalibreContext context, IOptions<BibblanOptions> options)
{
_options = options.Value;
_context = context;
@ -43,7 +43,7 @@ namespace Bibblan.Business.Services
Comments = comment.Text,
Language = l.LangCode,
Path = b.Path,
HasCover = b.HasCover == "1",
HasCover = b.HasCover,// == "1",
Formats = (from d in _context.Data where d.Book == b.Id orderby d.Format select new DataVm { Id = d.Id, Format = d.Format, FileName = d.Name + "." + d.Format.ToLower() }).ToList(),
SeriesName = s.Name,
SeriesNumber = b.SeriesIndex

View File

@ -1,6 +1,8 @@
using Bibblan.Business.Services;
using Bibblan.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
namespace Bibblan.Controllers
{
@ -9,8 +11,13 @@ namespace Bibblan.Controllers
public class CalibreController : ControllerBase
{
CalibreService _service;
public CalibreController(CalibreService service) {
PostgresCalibreContext _postgresContext;
SqliteCalibreContext _sqliteContext;
public CalibreController(CalibreService service, SqliteCalibreContext sqliteContext, PostgresCalibreContext postgresContext) {
_service = service;
_postgresContext = postgresContext;
_sqliteContext = sqliteContext;
}
[HttpGet("books")]
@ -27,5 +34,278 @@ namespace Bibblan.Controllers
return File(bytes, "image/jpeg", true);
}
[HttpGet("dump")]
public IActionResult Dump()
{
//var e = _postgresContext.Database.EnsureCreated();
//var script = _postgresContext.Database.GenerateCreateScript();
// _postgresContext.Database.ExecuteSqlRaw(script);
var books = 1;// DumpBooks();
var auhtors = 1;// DumpAuthors();
var comments = 1;// DumpComments();
var data = 1;// DumpData();
var identifiers = 1;// DumpIdentifiers();
var languages = 1;// DumpLanguages();
var publishers = 1;// DumpPublishers();
var ratings = 1;// DumpRatings();
var series = 1;// DumpSeries();
var tags = 1;// DumpTags();
var ba = 1;// Dumpa(_postgresContext, _sqliteContext.BooksAuthorsLink.OrderBy(x => x.Id), _postgresContext.BooksAuthorsLink);
var bl = 1;// Dumpa(_postgresContext, _sqliteContext.BooksLanguagesLink.OrderBy(x => x.Id), _postgresContext.BooksLanguagesLink);
var bp = 1;// Dumpa(_postgresContext, _sqliteContext.BooksPublishersLink.OrderBy(x => x.Id), _postgresContext.BooksPublishersLink);
var br = 1;// Dumpa(_postgresContext, _sqliteContext.BooksRatingsLink.OrderBy(x => x.Id), _postgresContext.BooksRatingsLink);
var bs = 1;// Dumpa(_postgresContext, _sqliteContext.BooksSeriesLink.OrderBy(x => x.Id), _postgresContext.BooksSeriesLink);
var bt = 1;// Dumpa(_postgresContext, _sqliteContext.BooksTagsLink.OrderBy(x => x.Id), _postgresContext.BooksTagsLink);
return Ok(new
{
books,
auhtors,
comments,
data,
identifiers,
languages,
publishers,
ratings,
series,
tags,
links = new
{
ba,
bl,
bp,
br,
bs,
bt
}
});
}
private int Dumpa<T>(DbContext toContext, IQueryable<T> from, DbSet<T> to)
where T : class
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var records = from.Skip(current).Take(step);
done = records.Count() == 0;
foreach (var record in records)
{
to.Add(record);
}
toContext.SaveChanges();
current += step;
}
return current;
}
private int DumpBooks() {
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var books = _sqliteContext.Books.OrderBy(b => b.Id).Skip(current).Take(step);
done = books.Count() == 0;
foreach (var book in books)
{
_postgresContext.Books.Add(book);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpAuthors()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var authors = _sqliteContext.Authors.OrderBy(b => b.Id).Skip(current).Take(step);
done = authors.Count() == 0;
foreach (var author in authors)
{
_postgresContext.Authors.Add(author);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpComments()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var comments = _sqliteContext.Comments.OrderBy(b => b.Id).Skip(current).Take(step);
done = comments.Count() == 0;
foreach (var comment in comments)
{
_postgresContext.Comments.Add(comment);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpData()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var data = _sqliteContext.Data.OrderBy(b => b.Id).Skip(current).Take(step);
done = data.Count() == 0;
foreach (var d in data)
{
_postgresContext.Data.Add(d);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpIdentifiers()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var identifiers = _sqliteContext.Identifiers.OrderBy(b => b.Id).Skip(current).Take(step);
done = identifiers.Count() == 0;
foreach (var id in identifiers)
{
_postgresContext.Identifiers.Add(id);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpLanguages()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var languages = _sqliteContext.Languages.OrderBy(b => b.Id).Skip(current).Take(step);
done = languages.Count() == 0;
foreach (var lang in languages)
{
_postgresContext.Languages.Add(lang);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpPublishers()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var publishers = _sqliteContext.Publishers.OrderBy(b => b.Id).Skip(current).Take(step);
done = publishers.Count() == 0;
foreach (var pub in publishers)
{
if(pub.Sort == null)
{
pub.Sort = pub.Name;
}
_postgresContext.Publishers.Add(pub);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpRatings()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var ratings = _sqliteContext.Ratings.OrderBy(b => b.Id).Skip(current).Take(step);
done = ratings.Count() == 0;
foreach (var rating in ratings)
{
_postgresContext.Ratings.Add(rating);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpSeries()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var series = _sqliteContext.Series.OrderBy(b => b.Id).Skip(current).Take(step);
done = series.Count() == 0;
foreach (var ser in series)
{
_postgresContext.Series.Add(ser);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
private int DumpTags()
{
var current = 0;
int step = 100;
var done = false;
while (!done)
{
var tags = _sqliteContext.Tags.OrderBy(b => b.Id).Skip(current).Take(step);
done = tags.Count() == 0;
foreach (var tag in tags)
{
_postgresContext.Tags.Add(tag);
}
_postgresContext.SaveChanges();
current += step;
}
return current;
}
}
}

View File

@ -6,5 +6,6 @@
public string CalibreDb { get; set; } = String.Empty;
public string CalibreRoot { get; set; } = String.Empty;
public string BibblanConnection { get; set; } = String.Empty;
}
}

View File

@ -15,8 +15,8 @@ namespace Bibblan.Models
public long Id { get; set; }
public string Title { get; set; }
public string Sort { get; set; }
public string Timestamp { get; set; }
public string Pubdate { get; set; }
public DateTime Timestamp { get; set; }
public DateTime Pubdate { get; set; }
public double SeriesIndex { get; set; }
public string AuthorSort { get; set; }
public string Isbn { get; set; }
@ -24,8 +24,8 @@ namespace Bibblan.Models
public string Path { get; set; }
public long Flags { get; set; }
public string Uuid { get; set; }
public string HasCover { get; set; }
public string LastModified { get; set; }
public bool HasCover { get; set; }
public DateTime LastModified { get; set; }
}
public partial class BooksAuthorsLink
@ -101,11 +101,11 @@ namespace Bibblan.Models
public string Label { get; set; }
public string Name { get; set; }
public string Datatype { get; set; }
public string MarkForDelete { get; set; }
public string Editable { get; set; }
public bool MarkForDelete { get; set; }
public bool Editable { get; set; }
public string Display { get; set; }
public string IsMultiple { get; set; }
public string Normalized { get; set; }
public bool IsMultiple { get; set; }
public bool Normalized { get; set; }
}
public partial class Data
@ -161,7 +161,7 @@ namespace Bibblan.Models
{
public long Id { get; set; }
public string Name { get; set; }
public string Sort { get; set; }
public string? Sort { get; set; }
}
public partial class Ratings
@ -183,7 +183,7 @@ namespace Bibblan.Models
public string Name { get; set; }
}
public partial class CalibreContext : DbContext
public partial class BaseContext : DbContext
{
public virtual DbSet<Authors> Authors { get; set; }
public virtual DbSet<Books> Books { get; set; }
@ -209,7 +209,7 @@ namespace Bibblan.Models
public virtual DbSet<Series> Series { get; set; }
public virtual DbSet<Tags> Tags { get; set; }
public CalibreContext(DbContextOptions<CalibreContext> options) : base(options)
public BaseContext(DbContextOptions options) : base(options)
{
}
@ -762,4 +762,20 @@ namespace Bibblan.Models
});
}
}
public partial class SqliteCalibreContext : BaseContext
{
public SqliteCalibreContext(DbContextOptions<SqliteCalibreContext> options) : base(options)
{
}
}
public partial class PostgresCalibreContext : BaseContext
{
public PostgresCalibreContext(DbContextOptions<PostgresCalibreContext> options) : base(options)
{
}
}
}

View File

@ -1,12 +1,16 @@
using Bibblan.Business.Services;
using Bibblan.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile($"appsettings.user.json", true, true);
var configSection = builder.Configuration.GetSection(BibblanOptions.Bibblan);
BibblanOptions config = new();
configSection.Bind(config);
// Add services to the container.
builder.Services.Configure<BibblanOptions>(
builder.Configuration.GetSection(BibblanOptions.Bibblan));
builder.Services.Configure<BibblanOptions>(configSection);
builder.Services.AddScoped<CalibreService, CalibreService>();
@ -16,9 +20,9 @@ builder.Services.AddControllers();
builder.Services.AddOpenApi();
var db = "metadata.db";
var connection = $"Data Source={db};Mode=ReadOnly;";
builder.Services.AddDbContext<CalibreContext>(options => options.UseSqlite(connection));
builder.Services.AddDbContext<SqliteCalibreContext>(options => options.UseSqlite($"Data Source={config.CalibreDb};Mode=ReadOnly;"));
builder.Services.AddDbContext<PostgresCalibreContext>(options => options.UseNpgsql(config.BibblanConnection));
var app = builder.Build();

View File

@ -8,6 +8,7 @@
"AllowedHosts": "*",
"Bibblan": {
"CalibreDb": "metadata.db",
"CalibreRoot": "\\\\diskstation\\Books\\"
"CalibreRoot": "c:\\my_books\\",
"BibblanConnection": "Server=localhost;Port=5432;Database=bibblan;User Id=bibblanuser;Password=1234567;"
}
}