0
0

Compare commits

..

No commits in common. "3ab838e27f488088d32eb9a1bd239521185a131d" and "402ffae02d2ee0c48e8220500c03e588a5d57f15" have entirely different histories.

21 changed files with 334 additions and 120 deletions

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RhSolutions.Api\RhSolutions.Api.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@
using RhSolutions.Api.Models;
namespace RhSolutions.Tests
{
public class SkuExtensionsTests
{
[Theory]
[InlineData("11600011001")]
[InlineData(" 11600011001")]
[InlineData("11600011001 ")]
[InlineData("string 11600011001")]
[InlineData("11600011001 string")]
[InlineData("160001-001")]
[InlineData("string 160001-001")]
[InlineData("160001-001 string")]
[InlineData("160001001")]
[InlineData("string 160001001")]
[InlineData("160001001 string")]
public void TestName(string input)
{
Sku.TryParse(input, out IEnumerable<Sku> sku);
Assert.Equal(new Sku("160001", "001"), sku.FirstOrDefault());
}
}
}

View File

@ -0,0 +1 @@
global using Xunit;

View File

@ -1,7 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using RhSolutions.Models; using RhSolutions.Api.Models;
using RhSolutions.Api.Services; using RhSolutions.Api.Services;
using System.Linq;
namespace RhSolutions.Api.Controllers namespace RhSolutions.Api.Controllers
{ {
@ -32,25 +31,17 @@ namespace RhSolutions.Api.Controllers
} }
[HttpPost] [HttpPost]
public IActionResult PostProductsFromXls() public async Task<IActionResult> PostProductsFromXls()
{ {
try try
{ {
var products = parser.GetProducts(HttpContext).GroupBy(p => p.ProductSku) var products = parser.GetProducts(HttpContext);
.Select(g => new Product(g.Key) await foreach (var p in products)
{
Name = g.First().Name,
DeprecatedSkus = g.SelectMany(p => p.DeprecatedSkus).ToList(),
ProductLines = g.SelectMany(p => p.ProductLines).Distinct().ToList(),
IsOnWarehouse = g.Any(p => p.IsOnWarehouse == true),
ProductMeasure = g.First().ProductMeasure,
DeliveryMakeUp = g.First().DeliveryMakeUp,
Price = g.First().Price
});
foreach (var p in products)
{ {
dbContext.Add<Product>(p); using (p)
{
dbContext.Add<Product>(p);
}
} }
dbContext.SaveChanges(); dbContext.SaveChanges();

View File

@ -1,27 +1,28 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using RhSolutions.Models; using RhSolutions.Api.Models;
namespace RhSolutions.Api.Controllers namespace RhSolutions.Api.Controllers
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
public class SearchController : ControllerBase public class SearchController : ControllerBase
{ {
private RhSolutionsContext context; private RhSolutionsContext context;
public SearchController(RhSolutionsContext context) public SearchController(RhSolutionsContext context)
{ {
this.context = context; this.context = context;
} }
[HttpGet] [HttpGet]
public IAsyncEnumerable<Product> SearchProducts([FromQuery] string query) public IAsyncEnumerable<Product> SearchProducts([FromQuery] string query)
{ {
return context.Products return context.Products
.Where(p => EF.Functions.ToTsVector( .Where(p => EF.Functions.ToTsVector(
"russian", string.Join(' ', new[] { p.Name, string.Join(' ', p.ProductLines)})) "russian", string.Join(' ',
.Matches(EF.Functions.WebSearchToTsQuery("russian", query))) new [] {p.ProductLine ?? string.Empty, p.Name ?? string.Empty }))
.AsAsyncEnumerable(); .Matches(EF.Functions.WebSearchToTsQuery("russian", query)))
} .AsAsyncEnumerable();
} }
}
} }

View File

@ -6,14 +6,14 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using RhSolutions.Models; using RhSolutions.Api.Models;
#nullable disable #nullable disable
namespace RhSolutions.Api.Migrations namespace RhSolutions.Api.Migrations
{ {
[DbContext(typeof(RhSolutionsContext))] [DbContext(typeof(RhSolutionsContext))]
[Migration("20230511043408_Init")] [Migration("20221201071323_Init")]
partial class Init partial class Init
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -21,15 +21,18 @@ namespace RhSolutions.Api.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "7.0.5") .HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("RhSolutions.Models.Product", b => modelBuilder.Entity("RhSolutions.Api.Models.Product", b =>
{ {
b.Property<string>("Id") b.Property<int>("Id")
.HasColumnType("text"); .ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<double?>("DeliveryMakeUp") b.Property<double?>("DeliveryMakeUp")
.HasColumnType("double precision"); .HasColumnType("double precision");
@ -38,7 +41,7 @@ namespace RhSolutions.Api.Migrations
.IsRequired() .IsRequired()
.HasColumnType("text[]"); .HasColumnType("text[]");
b.Property<bool>("IsOnWarehouse") b.Property<bool?>("IsOnWarehouse")
.HasColumnType("boolean"); .HasColumnType("boolean");
b.Property<string>("Name") b.Property<string>("Name")
@ -46,17 +49,15 @@ namespace RhSolutions.Api.Migrations
.HasColumnType("text"); .HasColumnType("text");
b.Property<decimal>("Price") b.Property<decimal>("Price")
.HasColumnType("numeric"); .HasColumnType("decimal(8,2)");
b.Property<List<string>>("ProductLines") b.Property<string>("ProductLine")
.IsRequired() .HasColumnType("text");
.HasColumnType("text[]");
b.Property<int>("ProductMeasure") b.Property<int>("ProductMeasure")
.HasColumnType("integer"); .HasColumnType("integer");
b.Property<string>("ProductSku") b.Property<string>("ProductSku")
.IsRequired()
.HasColumnType("text"); .HasColumnType("text");
b.HasKey("Id"); b.HasKey("Id");

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable #nullable disable
@ -15,15 +16,16 @@ namespace RhSolutions.Api.Migrations
name: "Products", name: "Products",
columns: table => new columns: table => new
{ {
Id = table.Column<string>(type: "text", nullable: false), Id = table.Column<int>(type: "integer", nullable: false)
Name = table.Column<string>(type: "text", nullable: false), .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ProductSku = table.Column<string>(type: "text", nullable: false), ProductSku = table.Column<string>(type: "text", nullable: true),
DeprecatedSkus = table.Column<List<string>>(type: "text[]", nullable: false), DeprecatedSkus = table.Column<List<string>>(type: "text[]", nullable: false),
ProductLines = table.Column<List<string>>(type: "text[]", nullable: false), Name = table.Column<string>(type: "text", nullable: false),
IsOnWarehouse = table.Column<bool>(type: "boolean", nullable: false), ProductLine = table.Column<string>(type: "text", nullable: true),
IsOnWarehouse = table.Column<bool>(type: "boolean", nullable: true),
ProductMeasure = table.Column<int>(type: "integer", nullable: false), ProductMeasure = table.Column<int>(type: "integer", nullable: false),
DeliveryMakeUp = table.Column<double>(type: "double precision", nullable: true), DeliveryMakeUp = table.Column<double>(type: "double precision", nullable: true),
Price = table.Column<decimal>(type: "numeric", nullable: false) Price = table.Column<decimal>(type: "numeric(8,2)", nullable: false)
}, },
constraints: table => constraints: table =>
{ {

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using RhSolutions.Models; using RhSolutions.Api.Models;
#nullable disable #nullable disable
@ -18,15 +18,18 @@ namespace RhSolutions.Api.Migrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "7.0.5") .HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63); .HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("RhSolutions.Models.Product", b => modelBuilder.Entity("RhSolutions.Api.Models.Product", b =>
{ {
b.Property<string>("Id") b.Property<int>("Id")
.HasColumnType("text"); .ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<double?>("DeliveryMakeUp") b.Property<double?>("DeliveryMakeUp")
.HasColumnType("double precision"); .HasColumnType("double precision");
@ -35,7 +38,7 @@ namespace RhSolutions.Api.Migrations
.IsRequired() .IsRequired()
.HasColumnType("text[]"); .HasColumnType("text[]");
b.Property<bool>("IsOnWarehouse") b.Property<bool?>("IsOnWarehouse")
.HasColumnType("boolean"); .HasColumnType("boolean");
b.Property<string>("Name") b.Property<string>("Name")
@ -43,17 +46,15 @@ namespace RhSolutions.Api.Migrations
.HasColumnType("text"); .HasColumnType("text");
b.Property<decimal>("Price") b.Property<decimal>("Price")
.HasColumnType("numeric"); .HasColumnType("decimal(8,2)");
b.Property<List<string>>("ProductLines") b.Property<string>("ProductLine")
.IsRequired() .HasColumnType("text");
.HasColumnType("text[]");
b.Property<int>("ProductMeasure") b.Property<int>("ProductMeasure")
.HasColumnType("integer"); .HasColumnType("integer");
b.Property<string>("ProductSku") b.Property<string>("ProductSku")
.IsRequired()
.HasColumnType("text"); .HasColumnType("text");
b.HasKey("Id"); b.HasKey("Id");

View File

@ -0,0 +1,4 @@
namespace RhSolutions.Api.Models
{
public enum Measure { Kg, M, M2, P }
}

View File

@ -0,0 +1,34 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Text.Json.Serialization;
namespace RhSolutions.Api.Models
{
public partial class Product : IDisposable
{
[Key]
[JsonIgnore]
public int Id { get; set; }
public string ProductSku { get; set; } = string.Empty;
public List<string> DeprecatedSkus { get; set; } = new();
public string Name { get; set; } = string.Empty;
public string ProductLine { get; set; } = string.Empty;
public bool? IsOnWarehouse { get; set; }
public Measure ProductMeasure { get; set; }
public double? DeliveryMakeUp { get; set; }
[Column(TypeName = "decimal(8,2)")]
public decimal Price { get; set; }
public void Dispose()
{
Debug.WriteLine($"{this} disposed");
}
public override string ToString()
{
return $"({ProductSku}) {Name}";
}
}
}

View File

@ -1,21 +1,11 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace RhSolutions.Models; namespace RhSolutions.Api.Models;
public class RhSolutionsContext : DbContext public class RhSolutionsContext : DbContext
{ {
public RhSolutionsContext(DbContextOptions<RhSolutionsContext> options) public RhSolutionsContext(DbContextOptions<RhSolutionsContext> options)
: base(options) { } : base(options) { }
public DbSet<Product> Products => Set<Product>(); public DbSet<Product> Products => Set<Product>();
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Product>()
.Property(e => e.ProductSku)
.HasConversion(v => v.ToString(), v => new ProductSku(v));
builder.Entity<Product>()
.Property(e => e.DeprecatedSkus)
.HasPostgresArrayConversion<ProductSku, string>(v => v.ToString(), v => new ProductSku(v));
}
} }

View File

@ -0,0 +1,127 @@
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace RhSolutions.Api.Models
{
public class Sku
{
private const string matchPattern = @"([1\D]|\b)(?<Article>\d{6})([1\s-]|)(?<Variant>\d{3})\b";
private string? _article;
private string? _variant;
public Sku(string article, string variant)
{
Article = article;
Variant = variant;
}
[Key]
public string Id
{
get
{
return $"1{Article}1{Variant}";
}
set
{
if (TryParse(value, out IEnumerable<Sku> skus))
{
if (skus.Count() > 1)
{
throw new ArgumentException($"More than one valid sku detected: {value}");
}
else
{
this.Article = skus.First().Article;
this.Variant = skus.First().Variant;
}
}
else
{
throw new ArgumentException($"Invalid sku input: {value}");
}
}
}
public string? Article
{
get
{
return _article;
}
set
{
if (value == null || value.Length != 6 || value.Where(c => char.IsDigit(c)).Count() != 6)
{
throw new ArgumentException($"Wrong Article: {Article}");
}
else
{
_article = value;
}
}
}
public string? Variant
{
get
{
return _variant;
}
set
{
if (value == null || value.Length != 3 || value.Where(c => char.IsDigit(c)).Count() != 3)
{
throw new ArgumentException($"Wrong Variant: {Variant}");
}
else _variant = value;
}
}
public static IEnumerable<Sku> GetValidSkus(string line)
{
MatchCollection matches = Regex.Matches(line, matchPattern);
if (matches.Count == 0)
{
yield break;
}
else
{
foreach (Match m in matches)
{
yield return new Sku(m.Groups["Article"].Value, m.Groups["Variant"].Value);
}
}
}
public static bool TryParse(string line, out IEnumerable<Sku> skus)
{
MatchCollection matches = Regex.Matches(line, matchPattern);
if (matches.Count == 0)
{
skus = Enumerable.Empty<Sku>();
return false;
}
else
{
skus = GetValidSkus(line);
return true;
}
}
public override bool Equals(object? obj)
{
return obj is Sku sku &&
Article!.Equals(sku.Article) &&
Variant!.Equals(sku.Variant);
}
public override int GetHashCode()
{
return HashCode.Combine(Article, Variant);
}
public override string ToString()
{
return $"1{Article}1{Variant}";
}
}
}

View File

@ -1,5 +1,5 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using RhSolutions.Models; using RhSolutions.Api.Models;
using RhSolutions.Api.Services; using RhSolutions.Api.Services;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);

View File

@ -8,14 +8,13 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ClosedXML" Version="0.101.0" /> <PackageReference Include="ClosedXML" Version="0.97.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.5"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.0" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.0" />
<PackageReference Include="Rhsolutions.ProductSku" Version="0.2.13" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,36 +1,35 @@
using ClosedXML.Excel; using ClosedXML.Excel;
using RhSolutions.Models; using RhSolutions.Api.Models;
namespace RhSolutions.Api.Services namespace RhSolutions.Api.Services
{ {
public class ClosedXMLParser : IPricelistParser public class ClosedXMLParser : IPricelistParser
{ {
public List<Product> GetProducts(HttpContext context) public async IAsyncEnumerable<Product> GetProducts(HttpContext context)
{ {
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{ {
if (context == null) if (context == null)
{ {
return new List<Product>(); yield break;
} }
context.Request.Body.CopyToAsync(memoryStream).GetAwaiter().GetResult(); await context.Request.Body.CopyToAsync(memoryStream);
List<Product> products = new();
using (var wb = new XLWorkbook(memoryStream)) using (var wb = new XLWorkbook(memoryStream))
{ {
Dictionary<ProductSku, Product> collected = new();
var table = GetTable(wb); var table = GetTable(wb);
var rows = table.DataRange.Rows(); var rows = table.DataRange.Rows();
foreach (var row in rows) var enumerator = rows.GetEnumerator();
while (enumerator.MoveNext())
{ {
if (ProductSku.TryParse(row.Field("Актуальный материал") if (Sku.TryParse(enumerator.Current.Field("Актуальный материал")
.GetString(), out _)) .GetString(), out IEnumerable<Sku> skus))
{ {
products.Add(ParseRow(row)); yield return ParseRow(enumerator.Current);
} }
} }
yield break;
} }
return products;
} }
} }
private IXLTable GetTable(XLWorkbook wb) private IXLTable GetTable(XLWorkbook wb)
@ -61,10 +60,10 @@ namespace RhSolutions.Api.Services
.GetString() .GetString()
.Split('\n') .Split('\n')
.First(); .First();
ProductSku.TryParse(row.Field("Актуальный материал") Sku.TryParse(row.Field("Актуальный материал")
.GetString(), out IEnumerable<ProductSku> productSkus); .GetString(), out IEnumerable<Sku> productSkus);
ProductSku.TryParse(row.Field("Прежний материал") Sku.TryParse(row.Field("Прежний материал")
.GetString(), out IEnumerable<ProductSku> deprecatedSkus); .GetString(), out IEnumerable<Sku> deprecatedSkus);
string measureField = new string(row.Field("Ед. изм.") string measureField = new string(row.Field("Ед. изм.")
.GetString() .GetString()
@ -101,7 +100,7 @@ namespace RhSolutions.Api.Services
string onWarehouseField = row.Field("Складская программа") string onWarehouseField = row.Field("Складская программа")
.GetString(); .GetString();
bool IsOnWarehouse; bool? IsOnWarehouse;
switch (onWarehouseField) switch (onWarehouseField)
{ {
@ -112,7 +111,7 @@ namespace RhSolutions.Api.Services
IsOnWarehouse = false; IsOnWarehouse = false;
break; break;
default: default:
IsOnWarehouse = false; IsOnWarehouse = null;
break; break;
} }
@ -124,11 +123,12 @@ namespace RhSolutions.Api.Services
price = 0.0M; price = 0.0M;
} }
return new Product(productSkus.First()) return new Product
{ {
ProductLines = new List<string>() { productLine }, ProductLine = productLine,
Name = productName, Name = productName,
DeprecatedSkus = deprecatedSkus.ToList(), ProductSku = productSkus.First().Id,
DeprecatedSkus = deprecatedSkus.Select(s => s.Id).ToList(),
ProductMeasure = productMeasure, ProductMeasure = productMeasure,
DeliveryMakeUp = productWarehouseCount, DeliveryMakeUp = productWarehouseCount,
IsOnWarehouse = IsOnWarehouse, IsOnWarehouse = IsOnWarehouse,

View File

@ -1,9 +1,9 @@
using RhSolutions.Models; using RhSolutions.Api.Models;
namespace RhSolutions.Api.Services namespace RhSolutions.Api.Services
{ {
public interface IPricelistParser public interface IPricelistParser
{ {
public List<Product> GetProducts(HttpContext context); public IAsyncEnumerable<Product> GetProducts(HttpContext context);
} }
} }

View File

@ -1,5 +1,5 @@
{ {
"sdk": { "sdk": {
"version": "6.0.311" "version": "6.0.402"
} }
} }

View File

@ -7,19 +7,19 @@ CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (
START TRANSACTION; START TRANSACTION;
CREATE TABLE "Products" ( CREATE TABLE "Products" (
"Id" text NOT NULL, "Id" integer GENERATED BY DEFAULT AS IDENTITY,
"Name" text NOT NULL, "ProductSku" text NULL,
"ProductSku" text NOT NULL,
"DeprecatedSkus" text[] NOT NULL, "DeprecatedSkus" text[] NOT NULL,
"ProductLines" text[] NOT NULL, "Name" text NOT NULL,
"IsOnWarehouse" boolean NOT NULL, "ProductLine" text NULL,
"IsOnWarehouse" boolean NULL,
"ProductMeasure" integer NOT NULL, "ProductMeasure" integer NOT NULL,
"DeliveryMakeUp" double precision NULL, "DeliveryMakeUp" double precision NULL,
"Price" numeric NOT NULL, "Price" numeric(8,2) NOT NULL,
CONSTRAINT "PK_Products" PRIMARY KEY ("Id") CONSTRAINT "PK_Products" PRIMARY KEY ("Id")
); );
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20230511043408_Init', '7.0.5'); VALUES ('20221201071323_Init', '7.0.0');
COMMIT; COMMIT;

View File

@ -1,8 +1,9 @@
version: '3' version: '3'
services: services:
rhsolutions-api: rhsolutions-api:
build: .. build: ../RhSolutions.Api
container_name: rhsolutions-api container_name: rhsolutions-api
ports: ports:
- 5000:5000 - 5000:5000
@ -15,13 +16,16 @@ services:
depends_on: depends_on:
- rhsolutions-db - rhsolutions-db
restart: unless-stopped restart: unless-stopped
rhsolutions-db: rhsolutions-db:
container_name: rhsolutions-db container_name: rhsolutions-db
ports: build: ./database
- 5432:5432
build: ./Database
environment: environment:
- POSTGRES_USER=chebser - POSTGRES_USER=chebser
- POSTGRES_PASSWORD=Rehau-987 - POSTGRES_PASSWORD=Rehau-987
- POSTGRES_DB=rhsolutions - POSTGRES_DB=rhsolutions
restart: unless-stopped restart: unless-stopped
networks:
default:
name: rhsolutions

View File

@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Api", "RhSolutions.Api\RhSolutions.Api.csproj", "{FD778359-7E92-4B5C-A4F9-7942A28E58F5}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Api", "RhSolutions.Api\RhSolutions.Api.csproj", "{FD778359-7E92-4B5C-A4F9-7942A28E58F5}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Api.Tests", "RhSolutions.Api.Tests\RhSolutions.Api.Tests.csproj", "{A71CCD18-1D47-4DF5-B883-AF4D1CFB4F4E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -18,5 +20,9 @@ Global
{FD778359-7E92-4B5C-A4F9-7942A28E58F5}.Debug|Any CPU.Build.0 = Debug|Any CPU {FD778359-7E92-4B5C-A4F9-7942A28E58F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD778359-7E92-4B5C-A4F9-7942A28E58F5}.Release|Any CPU.ActiveCfg = Release|Any CPU {FD778359-7E92-4B5C-A4F9-7942A28E58F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD778359-7E92-4B5C-A4F9-7942A28E58F5}.Release|Any CPU.Build.0 = Release|Any CPU {FD778359-7E92-4B5C-A4F9-7942A28E58F5}.Release|Any CPU.Build.0 = Release|Any CPU
{A71CCD18-1D47-4DF5-B883-AF4D1CFB4F4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A71CCD18-1D47-4DF5-B883-AF4D1CFB4F4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A71CCD18-1D47-4DF5-B883-AF4D1CFB4F4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A71CCD18-1D47-4DF5-B883-AF4D1CFB4F4E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal