From 48328265be82833866bc32b2a12d70d12aca0470 Mon Sep 17 00:00:00 2001 From: JackSGA Date: Tue, 4 Mar 2025 03:54:00 +0100 Subject: [PATCH 01/10] added MirroredFrom to Package --- src/BaGetter.Core/Entities/AbstractContext.cs | 1 + src/BaGetter.Core/Entities/Package.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/BaGetter.Core/Entities/AbstractContext.cs b/src/BaGetter.Core/Entities/AbstractContext.cs index 3e1874493..d768f1b3e 100644 --- a/src/BaGetter.Core/Entities/AbstractContext.cs +++ b/src/BaGetter.Core/Entities/AbstractContext.cs @@ -102,6 +102,7 @@ private void BuildPackageEntity(EntityTypeBuilder package) package.Property(p => p.Summary).HasMaxLength(DefaultMaxStringLength); package.Property(p => p.Title).HasMaxLength(MaxPackageTitleLength); package.Property(p => p.RepositoryType).HasMaxLength(MaxRepositoryTypeLength); + package.Property(p => p.MirroredFrom).HasMaxLength(DefaultMaxStringLength); package.Ignore(p => p.Version); package.Ignore(p => p.IconUrlString); diff --git a/src/BaGetter.Core/Entities/Package.cs b/src/BaGetter.Core/Entities/Package.cs index d3c44ebdf..b28992e8e 100644 --- a/src/BaGetter.Core/Entities/Package.cs +++ b/src/BaGetter.Core/Entities/Package.cs @@ -36,6 +36,7 @@ public NuGetVersion Version public bool HasReadme { get; set; } public bool HasEmbeddedIcon { get; set; } public bool IsPrerelease { get; set; } + public string MirroredFrom { get; set; } public string ReleaseNotes { get; set; } public string Language { get; set; } public bool Listed { get; set; } From 4f27aa9c0f859657694af9605dcd1ad7aefca114 Mon Sep 17 00:00:00 2001 From: JackSGA Date: Tue, 4 Mar 2025 03:55:23 +0100 Subject: [PATCH 02/10] added GetServiceIndexUrl to UpstreamClients --- .../Upstream/Clients/DisabledUpstreamClient.cs | 7 ++++++- src/BaGetter.Core/Upstream/Clients/V2UpstreamClient.cs | 2 ++ src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs | 2 ++ src/BaGetter.Core/Upstream/IUpstreamClient.cs | 8 +++++++- src/BaGetter.Protocol/NuGetClient.cs | 5 ++++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs b/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs index 493a7116c..b0933da94 100644 --- a/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -31,4 +31,9 @@ public Task DownloadPackageOrNullAsync( { return Task.FromResult(null); } + + public string GetServiceIndexUrl() + { + return "http://disabled.upstream.client"; + } } diff --git a/src/BaGetter.Core/Upstream/Clients/V2UpstreamClient.cs b/src/BaGetter.Core/Upstream/Clients/V2UpstreamClient.cs index 434bdde3b..8cf12fe39 100644 --- a/src/BaGetter.Core/Upstream/Clients/V2UpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/Clients/V2UpstreamClient.cs @@ -68,6 +68,8 @@ public V2UpstreamClient( } + public string GetServiceIndexUrl() => _repository.PackageSource.Source; + public async Task> ListPackageVersionsAsync(string id, CancellationToken cancellationToken) { try diff --git a/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs b/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs index 20b96c34e..1c26cf72e 100644 --- a/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs @@ -7,6 +7,7 @@ using BaGetter.Protocol; using BaGetter.Protocol.Models; using Microsoft.Extensions.Logging; +using NuGet.Protocol.Core.Types; using NuGet.Versioning; namespace BaGetter.Core; @@ -29,6 +30,7 @@ public V3UpstreamClient(NuGetClient client, ILogger logger) _client = client; _logger = logger; } + public string GetServiceIndexUrl() => _client.ServiceIndexUrl; public async Task DownloadPackageOrNullAsync( string id, diff --git a/src/BaGetter.Core/Upstream/IUpstreamClient.cs b/src/BaGetter.Core/Upstream/IUpstreamClient.cs index 80458bf12..660d9df6d 100644 --- a/src/BaGetter.Core/Upstream/IUpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/IUpstreamClient.cs @@ -1,4 +1,4 @@ -using NuGet.Versioning; +using NuGet.Versioning; using System.Collections.Generic; using System.IO; using System.Threading; @@ -46,4 +46,10 @@ public interface IUpstreamClient /// The stream is guaranteed to be seekable if not not null. /// Task DownloadPackageOrNullAsync(string id, NuGetVersion version, CancellationToken cancellationToken); + + /// + /// Get the service index url from the upstream package source. + /// + /// The service index url as a string + string GetServiceIndexUrl(); } diff --git a/src/BaGetter.Protocol/NuGetClient.cs b/src/BaGetter.Protocol/NuGetClient.cs index 50cb305e9..3faf89d5a 100644 --- a/src/BaGetter.Protocol/NuGetClient.cs +++ b/src/BaGetter.Protocol/NuGetClient.cs @@ -21,6 +21,8 @@ public class NuGetClient private readonly ISearchClient _searchClient; private readonly IAutocompleteClient _autocompleteClient; + public string ServiceIndexUrl { get; } + /// /// Initializes a new instance of the class /// for mocking. @@ -50,6 +52,7 @@ public NuGetClient(string serviceIndexUrl) _metadataClient = clientFactory.CreatePackageMetadataClient(); _searchClient = clientFactory.CreateSearchClient(); _autocompleteClient = clientFactory.CreateAutocompleteClient(); + ServiceIndexUrl = serviceIndexUrl; } /// @@ -335,7 +338,7 @@ public virtual async Task> SearchAsync( int take, CancellationToken cancellationToken = default) { - var response = await _searchClient.SearchAsync( + var response = await _searchClient.SearchAsync( query, skip, take, From abd9acf60eef19383400d05b9a47d87c149eb7bf Mon Sep 17 00:00:00 2001 From: JackSGA Date: Tue, 4 Mar 2025 03:56:33 +0100 Subject: [PATCH 03/10] added mirrorFeedUrl to IPackageIndexingService.IndexAsync --- src/BaGetter.Core/Indexing/IPackageIndexingService.cs | 3 ++- src/BaGetter.Core/Indexing/PackageIndexingService.cs | 3 ++- src/BaGetter.Core/PackageService.cs | 9 ++++++--- src/BaGetter.Web/Controllers/PackagePublishController.cs | 2 +- .../BaGetter.Core.Tests/Services/PackageServiceTests.cs | 8 ++++---- tests/BaGetter.Tests/Support/BaGetApplication.cs | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/BaGetter.Core/Indexing/IPackageIndexingService.cs b/src/BaGetter.Core/Indexing/IPackageIndexingService.cs index 7e1b999f8..82cc62eeb 100644 --- a/src/BaGetter.Core/Indexing/IPackageIndexingService.cs +++ b/src/BaGetter.Core/Indexing/IPackageIndexingService.cs @@ -35,7 +35,8 @@ public interface IPackageIndexingService /// Attempt to index a new package. /// /// The stream containing the package's content. + /// The url of the feed the package has been mirrored in case of mirroring, else null. /// /// The result of the attempted indexing operation. - Task IndexAsync(Stream stream, CancellationToken cancellationToken); + Task IndexAsync(Stream stream, string mirrorFeedUrl = null, CancellationToken cancellationToken = default); } diff --git a/src/BaGetter.Core/Indexing/PackageIndexingService.cs b/src/BaGetter.Core/Indexing/PackageIndexingService.cs index ad015718d..9e8444176 100644 --- a/src/BaGetter.Core/Indexing/PackageIndexingService.cs +++ b/src/BaGetter.Core/Indexing/PackageIndexingService.cs @@ -45,7 +45,7 @@ public PackageIndexingService( #pragma warning restore CS0618 // Type or member is obsolete } - public async Task IndexAsync(Stream packageStream, CancellationToken cancellationToken) + public async Task IndexAsync(Stream packageStream, string mirrorFeedUrl = null, CancellationToken cancellationToken = default) { // Try to extract all the necessary information from the package. Package package; @@ -57,6 +57,7 @@ public async Task IndexAsync(Stream packageStream, Cancel { using var packageReader = new PackageArchiveReader(packageStream, leaveStreamOpen: true); package = packageReader.GetPackageMetadata(); + package.MirroredFrom = mirrorFeedUrl; package.Published = _time.UtcNow; nuspecStream = await packageReader.GetNuspecAsync(cancellationToken); diff --git a/src/BaGetter.Core/PackageService.cs b/src/BaGetter.Core/PackageService.cs index b5df07a21..0cb3f54cd 100644 --- a/src/BaGetter.Core/PackageService.cs +++ b/src/BaGetter.Core/PackageService.cs @@ -100,10 +100,13 @@ private async Task MirrorAsync(string id, NuGetVersion version, Cancellati return true; } + var mirrorFeedUrl = _upstream.GetServiceIndexUrl(); + _logger.LogInformation( - "Package {PackageId} {PackageVersion} does not exist locally. Checking upstream feed...", + "Package {PackageId} {PackageVersion} does not exist locally. Checking upstream feed ({mirrorFeedUrl})...", id, - version); + version, + mirrorFeedUrl); try { @@ -122,7 +125,7 @@ private async Task MirrorAsync(string id, NuGetVersion version, Cancellati id, version); - var result = await _indexer.IndexAsync(packageStream, cancellationToken); + var result = await _indexer.IndexAsync(packageStream, mirrorFeedUrl, cancellationToken); _logger.LogInformation( "Finished indexing package {PackageId} {PackageVersion} from upstream feed with result {Result}", diff --git a/src/BaGetter.Web/Controllers/PackagePublishController.cs b/src/BaGetter.Web/Controllers/PackagePublishController.cs index c66b3bbe1..6add0ebf5 100644 --- a/src/BaGetter.Web/Controllers/PackagePublishController.cs +++ b/src/BaGetter.Web/Controllers/PackagePublishController.cs @@ -53,7 +53,7 @@ public async Task Upload(CancellationToken cancellationToken) return; } - var result = await _indexer.IndexAsync(uploadStream, cancellationToken); + var result = await _indexer.IndexAsync(uploadStream, cancellationToken: cancellationToken); switch (result) { diff --git a/tests/BaGetter.Core.Tests/Services/PackageServiceTests.cs b/tests/BaGetter.Core.Tests/Services/PackageServiceTests.cs index 47215ab05..0a0553d87 100644 --- a/tests/BaGetter.Core.Tests/Services/PackageServiceTests.cs +++ b/tests/BaGetter.Core.Tests/Services/PackageServiceTests.cs @@ -283,7 +283,7 @@ public async Task SkipsIfAlreadyMirrored() await TargetAsync(); _indexer.Verify( - i => i.IndexAsync(It.IsAny(), _cancellationToken), + i => i.IndexAsync(It.IsAny(), _upstream.Object.GetServiceIndexUrl(), _cancellationToken), Times.Never); } @@ -301,7 +301,7 @@ public async Task SkipsIfUpstreamDoesntHavePackage() await TargetAsync(); _indexer.Verify( - i => i.IndexAsync(It.IsAny(), _cancellationToken), + i => i.IndexAsync(It.IsAny(), _upstream.Object.GetServiceIndexUrl(), _cancellationToken), Times.Never); } @@ -319,7 +319,7 @@ public async Task SkipsIfUpstreamThrows() await TargetAsync(); _indexer.Verify( - i => i.IndexAsync(It.IsAny(), _cancellationToken), + i => i.IndexAsync(It.IsAny(), _upstream.Object.GetServiceIndexUrl(), _cancellationToken), Times.Never); } @@ -338,7 +338,7 @@ public async Task MirrorsPackage() await TargetAsync(); _indexer.Verify( - i => i.IndexAsync(It.IsAny(), _cancellationToken), + i => i.IndexAsync(It.IsAny(), _upstream.Object.GetServiceIndexUrl(), _cancellationToken), Times.Once); } } diff --git a/tests/BaGetter.Tests/Support/BaGetApplication.cs b/tests/BaGetter.Tests/Support/BaGetApplication.cs index 6888e71e0..be46f378a 100644 --- a/tests/BaGetter.Tests/Support/BaGetApplication.cs +++ b/tests/BaGetter.Tests/Support/BaGetApplication.cs @@ -125,7 +125,7 @@ public static async Task AddPackageAsync( using var scope = scopeFactory.CreateScope(); var indexer = scope.ServiceProvider.GetRequiredService(); - var result = await indexer.IndexAsync(package, cancellationToken); + var result = await indexer.IndexAsync(package, cancellationToken: cancellationToken); if (result != PackageIndexingResult.Success) { throw new InvalidOperationException($"Unexpected indexing result {result}"); From ee6eebe03d2ab6282830e97020c3dab7ef8d6320 Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Wed, 10 Dec 2025 13:49:33 +0100 Subject: [PATCH 04/10] changed GetServiceIndexUrl() of DisabledUpstreamClient to return example.org based domain, cleanup of usings in V3UpstreamClient --- src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs | 2 +- src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs b/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs index b0933da94..cd8967d2c 100644 --- a/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs @@ -34,6 +34,6 @@ public Task DownloadPackageOrNullAsync( public string GetServiceIndexUrl() { - return "http://disabled.upstream.client"; + return "https://disabled-upstream-client.example.org"; } } diff --git a/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs b/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs index 1c26cf72e..33cf7e04f 100644 --- a/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/Clients/V3UpstreamClient.cs @@ -7,7 +7,6 @@ using BaGetter.Protocol; using BaGetter.Protocol.Models; using Microsoft.Extensions.Logging; -using NuGet.Protocol.Core.Types; using NuGet.Versioning; namespace BaGetter.Core; From 389a6918a96a65e6419f15176666ae0e5ee605ff Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Mon, 19 Jan 2026 13:04:44 +0100 Subject: [PATCH 05/10] renamed MirroredFrom to CachedFrom etc --- src/BaGetter.Core/Entities/AbstractContext.cs | 2 +- src/BaGetter.Core/Entities/Package.cs | 2 +- src/BaGetter.Core/Indexing/IPackageIndexingService.cs | 6 +++--- src/BaGetter.Core/Indexing/PackageIndexingService.cs | 4 ++-- src/BaGetter.Core/PackageService.cs | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/BaGetter.Core/Entities/AbstractContext.cs b/src/BaGetter.Core/Entities/AbstractContext.cs index d768f1b3e..fa5f9af9d 100644 --- a/src/BaGetter.Core/Entities/AbstractContext.cs +++ b/src/BaGetter.Core/Entities/AbstractContext.cs @@ -102,7 +102,7 @@ private void BuildPackageEntity(EntityTypeBuilder package) package.Property(p => p.Summary).HasMaxLength(DefaultMaxStringLength); package.Property(p => p.Title).HasMaxLength(MaxPackageTitleLength); package.Property(p => p.RepositoryType).HasMaxLength(MaxRepositoryTypeLength); - package.Property(p => p.MirroredFrom).HasMaxLength(DefaultMaxStringLength); + package.Property(p => p.CachedFrom).HasMaxLength(DefaultMaxStringLength); package.Ignore(p => p.Version); package.Ignore(p => p.IconUrlString); diff --git a/src/BaGetter.Core/Entities/Package.cs b/src/BaGetter.Core/Entities/Package.cs index b28992e8e..27795b571 100644 --- a/src/BaGetter.Core/Entities/Package.cs +++ b/src/BaGetter.Core/Entities/Package.cs @@ -36,7 +36,7 @@ public NuGetVersion Version public bool HasReadme { get; set; } public bool HasEmbeddedIcon { get; set; } public bool IsPrerelease { get; set; } - public string MirroredFrom { get; set; } + public string CachedFrom { get; set; } public string ReleaseNotes { get; set; } public string Language { get; set; } public bool Listed { get; set; } diff --git a/src/BaGetter.Core/Indexing/IPackageIndexingService.cs b/src/BaGetter.Core/Indexing/IPackageIndexingService.cs index 82cc62eeb..7dbd4df98 100644 --- a/src/BaGetter.Core/Indexing/IPackageIndexingService.cs +++ b/src/BaGetter.Core/Indexing/IPackageIndexingService.cs @@ -6,7 +6,7 @@ namespace BaGetter.Core; /// /// The result of attempting to index a package. -/// See . +/// See . /// public enum PackageIndexingResult { @@ -35,8 +35,8 @@ public interface IPackageIndexingService /// Attempt to index a new package. /// /// The stream containing the package's content. - /// The url of the feed the package has been mirrored in case of mirroring, else null. + /// The url of the feed the package has been cached from in case of pull through caching, else null. /// /// The result of the attempted indexing operation. - Task IndexAsync(Stream stream, string mirrorFeedUrl = null, CancellationToken cancellationToken = default); + Task IndexAsync(Stream stream, string cacheFeedUrl = null, CancellationToken cancellationToken = default); } diff --git a/src/BaGetter.Core/Indexing/PackageIndexingService.cs b/src/BaGetter.Core/Indexing/PackageIndexingService.cs index 9e8444176..4152fa8e8 100644 --- a/src/BaGetter.Core/Indexing/PackageIndexingService.cs +++ b/src/BaGetter.Core/Indexing/PackageIndexingService.cs @@ -45,7 +45,7 @@ public PackageIndexingService( #pragma warning restore CS0618 // Type or member is obsolete } - public async Task IndexAsync(Stream packageStream, string mirrorFeedUrl = null, CancellationToken cancellationToken = default) + public async Task IndexAsync(Stream packageStream, string cacheFeedUrl = null, CancellationToken cancellationToken = default) { // Try to extract all the necessary information from the package. Package package; @@ -57,7 +57,7 @@ public async Task IndexAsync(Stream packageStream, string { using var packageReader = new PackageArchiveReader(packageStream, leaveStreamOpen: true); package = packageReader.GetPackageMetadata(); - package.MirroredFrom = mirrorFeedUrl; + package.CachedFrom = cacheFeedUrl; package.Published = _time.UtcNow; nuspecStream = await packageReader.GetNuspecAsync(cancellationToken); diff --git a/src/BaGetter.Core/PackageService.cs b/src/BaGetter.Core/PackageService.cs index 0cb3f54cd..e6f8530d5 100644 --- a/src/BaGetter.Core/PackageService.cs +++ b/src/BaGetter.Core/PackageService.cs @@ -100,13 +100,13 @@ private async Task MirrorAsync(string id, NuGetVersion version, Cancellati return true; } - var mirrorFeedUrl = _upstream.GetServiceIndexUrl(); + var cacheFeedUrl = _upstream.GetServiceIndexUrl(); _logger.LogInformation( - "Package {PackageId} {PackageVersion} does not exist locally. Checking upstream feed ({mirrorFeedUrl})...", + "Package {PackageId} {PackageVersion} does not exist locally. Checking upstream feed ({cacheFeedUrl})...", id, version, - mirrorFeedUrl); + cacheFeedUrl); try { @@ -125,7 +125,7 @@ private async Task MirrorAsync(string id, NuGetVersion version, Cancellati id, version); - var result = await _indexer.IndexAsync(packageStream, mirrorFeedUrl, cancellationToken); + var result = await _indexer.IndexAsync(packageStream, cacheFeedUrl, cancellationToken); _logger.LogInformation( "Finished indexing package {PackageId} {PackageVersion} from upstream feed with result {Result}", From b1ceb861a8f6b5c038eb767560592f453da0544a Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Tue, 20 Jan 2026 13:51:12 +0100 Subject: [PATCH 06/10] added AddCachedFromToPackage migration for mysql --- ...0124318_AddCachedFromToPackage.Designer.cs | 264 ++++++++++++++++++ .../20260120124318_AddCachedFromToPackage.cs | 31 ++ .../Migrations/MySqlContextModelSnapshot.cs | 6 +- 3 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.Designer.cs create mode 100644 src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.cs diff --git a/src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.Designer.cs b/src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.Designer.cs new file mode 100644 index 000000000..5975c47d2 --- /dev/null +++ b/src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.Designer.cs @@ -0,0 +1,264 @@ +// +using System; +using BaGetter.Database.MySql; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BaGetter.Database.MySql.Migrations +{ + [DbContext(typeof(MySqlContext))] + [Migration("20260120124318_AddCachedFromToPackage")] + partial class AddCachedFromToPackage + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.HasCharSet(modelBuilder, "latin1"); + + modelBuilder.Entity("BaGetter.Core.Package", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Authors") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Description") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Downloads") + .HasColumnType("bigint"); + + b.Property("HasEmbeddedIcon") + .HasColumnType("tinyint(1)"); + + b.Property("HasReadme") + .HasColumnType("tinyint(1)"); + + b.Property("IconUrl") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Id") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("IsPrerelease") + .HasColumnType("tinyint(1)"); + + b.Property("Language") + .HasMaxLength(20) + .HasColumnType("varchar(20)"); + + b.Property("LicenseUrl") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Listed") + .HasColumnType("tinyint(1)"); + + b.Property("MinClientVersion") + .HasMaxLength(44) + .HasColumnType("varchar(44)"); + + b.Property("NormalizedVersionString") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("Version"); + + b.Property("OriginalVersionString") + .HasMaxLength(64) + .HasColumnType("varchar(64)") + .HasColumnName("OriginalVersion"); + + b.Property("ProjectUrl") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Published") + .HasColumnType("datetime(6)"); + + b.Property("ReleaseNotes") + .HasColumnType("longtext") + .HasColumnName("ReleaseNotes"); + + b.Property("RepositoryType") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("RepositoryUrl") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("RequireLicenseAcceptance") + .HasColumnType("tinyint(1)"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp(6)"); + + b.Property("SemVerLevel") + .HasColumnType("int"); + + b.Property("Summary") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Tags") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + + b.Property("Title") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("Id", "NormalizedVersionString") + .IsUnique(); + + b.ToTable("Packages"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("PackageKey") + .HasColumnType("int"); + + b.Property("TargetFramework") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("VersionRange") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageDependencies"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Name") + .HasMaxLength(512) + .HasColumnType("varchar(512)"); + + b.Property("PackageKey") + .HasColumnType("int"); + + b.Property("Version") + .HasMaxLength(64) + .HasColumnType("varchar(64)"); + + b.HasKey("Key"); + + b.HasIndex("Name"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageTypes"); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Moniker") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PackageKey") + .HasColumnType("int"); + + b.HasKey("Key"); + + b.HasIndex("Moniker"); + + b.HasIndex("PackageKey"); + + b.ToTable("TargetFrameworks"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("Dependencies") + .HasForeignKey("PackageKey"); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("PackageTypes") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("TargetFrameworks") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("BaGetter.Core.Package", b => + { + b.Navigation("Dependencies"); + + b.Navigation("PackageTypes"); + + b.Navigation("TargetFrameworks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.cs b/src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.cs new file mode 100644 index 000000000..032d40412 --- /dev/null +++ b/src/BaGetter.Database.MySql/Migrations/20260120124318_AddCachedFromToPackage.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BaGetter.Database.MySql.Migrations +{ + /// + public partial class AddCachedFromToPackage : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CachedFrom", + table: "Packages", + type: "varchar(4000)", + maxLength: 4000, + nullable: true) + .Annotation("MySql:CharSet", "latin1"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CachedFrom", + table: "Packages"); + } + } +} diff --git a/src/BaGetter.Database.MySql/Migrations/MySqlContextModelSnapshot.cs b/src/BaGetter.Database.MySql/Migrations/MySqlContextModelSnapshot.cs index 729a1cdd4..4f1994783 100644 --- a/src/BaGetter.Database.MySql/Migrations/MySqlContextModelSnapshot.cs +++ b/src/BaGetter.Database.MySql/Migrations/MySqlContextModelSnapshot.cs @@ -1,4 +1,4 @@ -// +// using System; using BaGetter.Database.MySql; using Microsoft.EntityFrameworkCore; @@ -31,6 +31,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(4000) .HasColumnType("varchar(4000)"); + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("varchar(4000)"); + b.Property("Description") .HasMaxLength(4000) .HasColumnType("varchar(4000)"); From f54b880a2d88efa94d0fcc84ebd398c18cd18032 Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Tue, 20 Jan 2026 13:53:39 +0100 Subject: [PATCH 07/10] added AddCachedFromToPackage migration for pgsql --- ...0124757_AddCachedFromToPackage.Designer.cs | 274 ++++++++++++++++++ .../20260120124757_AddCachedFromToPackage.cs | 29 ++ .../PostgreSqlContextModelSnapshot.cs | 4 + 3 files changed, 307 insertions(+) create mode 100644 src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.Designer.cs create mode 100644 src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.cs diff --git a/src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.Designer.cs b/src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.Designer.cs new file mode 100644 index 000000000..2ce6f32cc --- /dev/null +++ b/src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.Designer.cs @@ -0,0 +1,274 @@ +// +using System; +using BaGetter.Database.PostgreSql; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BaGetter.Database.PostgreSql.Migrations +{ + [DbContext(typeof(PostgreSqlContext))] + [Migration("20260120124757_AddCachedFromToPackage")] + partial class AddCachedFromToPackage + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "citext"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("BaGetter.Core.Package", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Key")); + + b.Property("Authors") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Description") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Downloads") + .HasColumnType("bigint"); + + b.Property("HasEmbeddedIcon") + .HasColumnType("boolean"); + + b.Property("HasReadme") + .HasColumnType("boolean"); + + b.Property("IconUrl") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Id") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("citext"); + + b.Property("IsPrerelease") + .HasColumnType("boolean"); + + b.Property("Language") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LicenseUrl") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Listed") + .HasColumnType("boolean"); + + b.Property("MinClientVersion") + .HasMaxLength(44) + .HasColumnType("character varying(44)"); + + b.Property("NormalizedVersionString") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("citext") + .HasColumnName("Version"); + + b.Property("OriginalVersionString") + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("OriginalVersion"); + + b.Property("ProjectUrl") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Published") + .HasColumnType("timestamp with time zone"); + + b.Property("ReleaseNotes") + .HasColumnType("text") + .HasColumnName("ReleaseNotes"); + + b.Property("RepositoryType") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("RepositoryUrl") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("RequireLicenseAcceptance") + .HasColumnType("boolean"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea"); + + b.Property("SemVerLevel") + .HasColumnType("integer"); + + b.Property("Summary") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Tags") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Title") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("Id", "NormalizedVersionString") + .IsUnique(); + + b.ToTable("Packages"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Key")); + + b.Property("Id") + .HasMaxLength(128) + .HasColumnType("citext"); + + b.Property("PackageKey") + .HasColumnType("integer"); + + b.Property("TargetFramework") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("VersionRange") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageDependencies"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Key")); + + b.Property("Name") + .HasMaxLength(512) + .HasColumnType("citext"); + + b.Property("PackageKey") + .HasColumnType("integer"); + + b.Property("Version") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Key"); + + b.HasIndex("Name"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageTypes"); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Key")); + + b.Property("Moniker") + .HasMaxLength(256) + .HasColumnType("citext"); + + b.Property("PackageKey") + .HasColumnType("integer"); + + b.HasKey("Key"); + + b.HasIndex("Moniker"); + + b.HasIndex("PackageKey"); + + b.ToTable("TargetFrameworks"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("Dependencies") + .HasForeignKey("PackageKey"); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("PackageTypes") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("TargetFrameworks") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Package"); + }); + + modelBuilder.Entity("BaGetter.Core.Package", b => + { + b.Navigation("Dependencies"); + + b.Navigation("PackageTypes"); + + b.Navigation("TargetFrameworks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.cs b/src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.cs new file mode 100644 index 000000000..f9bfb7b45 --- /dev/null +++ b/src/BaGetter.Database.PostgreSql/Migrations/20260120124757_AddCachedFromToPackage.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BaGetter.Database.PostgreSql.Migrations +{ + /// + public partial class AddCachedFromToPackage : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CachedFrom", + table: "Packages", + type: "character varying(4000)", + maxLength: 4000, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CachedFrom", + table: "Packages"); + } + } +} diff --git a/src/BaGetter.Database.PostgreSql/Migrations/PostgreSqlContextModelSnapshot.cs b/src/BaGetter.Database.PostgreSql/Migrations/PostgreSqlContextModelSnapshot.cs index 1f7738310..779553bef 100644 --- a/src/BaGetter.Database.PostgreSql/Migrations/PostgreSqlContextModelSnapshot.cs +++ b/src/BaGetter.Database.PostgreSql/Migrations/PostgreSqlContextModelSnapshot.cs @@ -35,6 +35,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(4000) .HasColumnType("character varying(4000)"); + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + b.Property("Description") .HasMaxLength(4000) .HasColumnType("character varying(4000)"); From 1d92d0737ca9a43c4e10ecf1ce85420973619610 Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Tue, 20 Jan 2026 14:03:23 +0100 Subject: [PATCH 08/10] added AddCachedFromToPackage migration for sqlite --- ...0125631_AddCachedFromToPackage.Designer.cs | 243 ++++++++++++++++++ .../20260120125631_AddCachedFromToPackage.cs | 29 +++ .../Migrations/SqliteContextModelSnapshot.cs | 4 + 3 files changed, 276 insertions(+) create mode 100644 src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.Designer.cs create mode 100644 src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.cs diff --git a/src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.Designer.cs b/src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.Designer.cs new file mode 100644 index 000000000..e3701d895 --- /dev/null +++ b/src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.Designer.cs @@ -0,0 +1,243 @@ +// +using System; +using BaGetter.Database.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace BaGetter.Database.Sqlite.Migrations +{ + [DbContext(typeof(SqliteContext))] + [Migration("20260120125631_AddCachedFromToPackage")] + partial class AddCachedFromToPackage + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.18"); + + modelBuilder.Entity("BaGetter.Core.Package", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Authors") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("Downloads") + .HasColumnType("INTEGER"); + + b.Property("HasEmbeddedIcon") + .HasColumnType("INTEGER"); + + b.Property("HasReadme") + .HasColumnType("INTEGER"); + + b.Property("IconUrl") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("Id") + .IsRequired() + .HasColumnType("TEXT COLLATE NOCASE") + .HasMaxLength(128); + + b.Property("IsPrerelease") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT") + .HasMaxLength(20); + + b.Property("LicenseUrl") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("Listed") + .HasColumnType("INTEGER"); + + b.Property("MinClientVersion") + .HasColumnType("TEXT") + .HasMaxLength(44); + + b.Property("NormalizedVersionString") + .IsRequired() + .HasColumnName("Version") + .HasColumnType("TEXT COLLATE NOCASE") + .HasMaxLength(64); + + b.Property("OriginalVersionString") + .HasColumnName("OriginalVersion") + .HasColumnType("TEXT") + .HasMaxLength(64); + + b.Property("ProjectUrl") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("Published") + .HasColumnType("TEXT"); + + b.Property("ReleaseNotes") + .HasColumnName("ReleaseNotes") + .HasColumnType("TEXT"); + + b.Property("RepositoryType") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("RepositoryUrl") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("RequireLicenseAcceptance") + .HasColumnType("INTEGER"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("BLOB"); + + b.Property("SemVerLevel") + .HasColumnType("INTEGER"); + + b.Property("Summary") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("Tags") + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.Property("Title") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("Id", "NormalizedVersionString") + .IsUnique(); + + b.ToTable("Packages"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Id") + .HasColumnType("TEXT COLLATE NOCASE") + .HasMaxLength(128); + + b.Property("PackageKey") + .HasColumnType("INTEGER"); + + b.Property("TargetFramework") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("VersionRange") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageDependencies"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT COLLATE NOCASE") + .HasMaxLength(512); + + b.Property("PackageKey") + .HasColumnType("INTEGER"); + + b.Property("Version") + .HasColumnType("TEXT") + .HasMaxLength(64); + + b.HasKey("Key"); + + b.HasIndex("Name"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageTypes"); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Moniker") + .HasColumnType("TEXT COLLATE NOCASE") + .HasMaxLength(256); + + b.Property("PackageKey") + .HasColumnType("INTEGER"); + + b.HasKey("Key"); + + b.HasIndex("Moniker"); + + b.HasIndex("PackageKey"); + + b.ToTable("TargetFrameworks"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("Dependencies") + .HasForeignKey("PackageKey"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("PackageTypes") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("TargetFrameworks") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.cs b/src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.cs new file mode 100644 index 000000000..b77073c40 --- /dev/null +++ b/src/BaGetter.Database.Sqlite/Migrations/20260120125631_AddCachedFromToPackage.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BaGetter.Database.Sqlite.Migrations +{ + /// + public partial class AddCachedFromToPackage : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CachedFrom", + table: "Packages", + type: "TEXT", + maxLength: 4000, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CachedFrom", + table: "Packages"); + } + } +} diff --git a/src/BaGetter.Database.Sqlite/Migrations/SqliteContextModelSnapshot.cs b/src/BaGetter.Database.Sqlite/Migrations/SqliteContextModelSnapshot.cs index 9d8b70cc4..d695821b3 100644 --- a/src/BaGetter.Database.Sqlite/Migrations/SqliteContextModelSnapshot.cs +++ b/src/BaGetter.Database.Sqlite/Migrations/SqliteContextModelSnapshot.cs @@ -26,6 +26,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("TEXT") .HasMaxLength(4000); + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("TEXT"); + b.Property("Description") .HasColumnType("TEXT") .HasMaxLength(4000); From dd29889648de9ffe5f6d570623384603ea779f59 Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Tue, 20 Jan 2026 14:08:20 +0100 Subject: [PATCH 09/10] added AddCachedFromToPackage migration for mssql --- ...0130456_AddCachedFromToPackage.Designer.cs | 250 ++++++++++++++++++ .../20260120130456_AddCachedFromToPackage.cs | 29 ++ .../SqlServerContextModelSnapshot.cs | 4 + 3 files changed, 283 insertions(+) create mode 100644 src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.Designer.cs create mode 100644 src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.cs diff --git a/src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.Designer.cs b/src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.Designer.cs new file mode 100644 index 000000000..ccbe366a7 --- /dev/null +++ b/src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.Designer.cs @@ -0,0 +1,250 @@ +// +using System; +using BaGetter.Database.SqlServer; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace BaGetter.Database.SqlServer.Migrations +{ + [DbContext(typeof(SqlServerContext))] + [Migration("20260120130456_AddCachedFromToPackage")] + partial class AddCachedFromToPackage + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.18") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("BaGetter.Core.Package", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Authors") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("Downloads") + .HasColumnType("bigint"); + + b.Property("HasEmbeddedIcon") + .HasColumnType("bit"); + + b.Property("HasReadme") + .HasColumnType("bit"); + + b.Property("IconUrl") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("Id") + .IsRequired() + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("IsPrerelease") + .HasColumnType("bit"); + + b.Property("Language") + .HasColumnType("nvarchar(20)") + .HasMaxLength(20); + + b.Property("LicenseUrl") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("Listed") + .HasColumnType("bit"); + + b.Property("MinClientVersion") + .HasColumnType("nvarchar(44)") + .HasMaxLength(44); + + b.Property("NormalizedVersionString") + .IsRequired() + .HasColumnName("Version") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("OriginalVersionString") + .HasColumnName("OriginalVersion") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.Property("ProjectUrl") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("Published") + .HasColumnType("datetime2"); + + b.Property("ReleaseNotes") + .HasColumnName("ReleaseNotes") + .HasColumnType("nvarchar(max)"); + + b.Property("RepositoryType") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("RepositoryUrl") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("RequireLicenseAcceptance") + .HasColumnType("bit"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.Property("SemVerLevel") + .HasColumnType("int"); + + b.Property("Summary") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("Tags") + .HasColumnType("nvarchar(4000)") + .HasMaxLength(4000); + + b.Property("Title") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("Id", "NormalizedVersionString") + .IsUnique(); + + b.ToTable("Packages"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Id") + .HasColumnType("nvarchar(128)") + .HasMaxLength(128); + + b.Property("PackageKey") + .HasColumnType("int"); + + b.Property("TargetFramework") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("VersionRange") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Key"); + + b.HasIndex("Id"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageDependencies"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Name") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PackageKey") + .HasColumnType("int"); + + b.Property("Version") + .HasColumnType("nvarchar(64)") + .HasMaxLength(64); + + b.HasKey("Key"); + + b.HasIndex("Name"); + + b.HasIndex("PackageKey"); + + b.ToTable("PackageTypes"); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.Property("Key") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Moniker") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PackageKey") + .HasColumnType("int"); + + b.HasKey("Key"); + + b.HasIndex("Moniker"); + + b.HasIndex("PackageKey"); + + b.ToTable("TargetFrameworks"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageDependency", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("Dependencies") + .HasForeignKey("PackageKey"); + }); + + modelBuilder.Entity("BaGetter.Core.PackageType", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("PackageTypes") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BaGetter.Core.TargetFramework", b => + { + b.HasOne("BaGetter.Core.Package", "Package") + .WithMany("TargetFrameworks") + .HasForeignKey("PackageKey") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.cs b/src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.cs new file mode 100644 index 000000000..eb8958119 --- /dev/null +++ b/src/BaGetter.Database.SqlServer/Migrations/20260120130456_AddCachedFromToPackage.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BaGetter.Database.SqlServer.Migrations +{ + /// + public partial class AddCachedFromToPackage : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CachedFrom", + table: "Packages", + type: "nvarchar(4000)", + maxLength: 4000, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CachedFrom", + table: "Packages"); + } + } +} diff --git a/src/BaGetter.Database.SqlServer/Migrations/SqlServerContextModelSnapshot.cs b/src/BaGetter.Database.SqlServer/Migrations/SqlServerContextModelSnapshot.cs index e18da18ab..d7245449f 100644 --- a/src/BaGetter.Database.SqlServer/Migrations/SqlServerContextModelSnapshot.cs +++ b/src/BaGetter.Database.SqlServer/Migrations/SqlServerContextModelSnapshot.cs @@ -30,6 +30,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(4000)") .HasMaxLength(4000); + b.Property("CachedFrom") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + b.Property("Description") .HasColumnType("nvarchar(4000)") .HasMaxLength(4000); From b85a5250188eef355d6c2e87b2ec3f2854f3c98b Mon Sep 17 00:00:00 2001 From: Alexander Engel Date: Tue, 24 Feb 2026 17:54:06 +0100 Subject: [PATCH 10/10] new IndexAsync overload & UpstreamClient adjustment --- src/BaGetter.Core/Indexing/IPackageIndexingService.cs | 8 ++++++++ src/BaGetter.Core/Indexing/PackageIndexingService.cs | 8 +++++++- .../Upstream/Clients/DisabledUpstreamClient.cs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/BaGetter.Core/Indexing/IPackageIndexingService.cs b/src/BaGetter.Core/Indexing/IPackageIndexingService.cs index 7dbd4df98..0ed430761 100644 --- a/src/BaGetter.Core/Indexing/IPackageIndexingService.cs +++ b/src/BaGetter.Core/Indexing/IPackageIndexingService.cs @@ -39,4 +39,12 @@ public interface IPackageIndexingService /// /// The result of the attempted indexing operation. Task IndexAsync(Stream stream, string cacheFeedUrl = null, CancellationToken cancellationToken = default); + + /// + /// Attempt to index a new package. + /// + /// The stream containing the package's content. + /// + /// The result of the attempted indexing operation. + Task IndexAsync(Stream stream, CancellationToken cancellationToken = default); } diff --git a/src/BaGetter.Core/Indexing/PackageIndexingService.cs b/src/BaGetter.Core/Indexing/PackageIndexingService.cs index 4152fa8e8..9dcfae19e 100644 --- a/src/BaGetter.Core/Indexing/PackageIndexingService.cs +++ b/src/BaGetter.Core/Indexing/PackageIndexingService.cs @@ -45,6 +45,11 @@ public PackageIndexingService( #pragma warning restore CS0618 // Type or member is obsolete } + public Task IndexAsync(Stream stream, CancellationToken cancellationToken = default) + { + return IndexAsync(stream, null, cancellationToken); + } + public async Task IndexAsync(Stream packageStream, string cacheFeedUrl = null, CancellationToken cancellationToken = default) { // Try to extract all the necessary information from the package. @@ -168,7 +173,8 @@ await _storage.SavePackageContentAsync( if (_retentionOptions.Value.MaxMajorVersions.HasValue) { - try { + try + { _logger.LogInformation( "Deleting older packages for package {PackageId} {PackageVersion}", package.Id, diff --git a/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs b/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs index cd8967d2c..df20abdae 100644 --- a/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs +++ b/src/BaGetter.Core/Upstream/Clients/DisabledUpstreamClient.cs @@ -34,6 +34,6 @@ public Task DownloadPackageOrNullAsync( public string GetServiceIndexUrl() { - return "https://disabled-upstream-client.example.org"; + return null; } }