diff --git a/docs/eShop-Db-Design.md b/docs/eShop-Db-Design.md new file mode 100644 index 0000000..f223d15 --- /dev/null +++ b/docs/eShop-Db-Design.md @@ -0,0 +1,25 @@ +# Nethereum eShop Db Design + +The eShop takes a hybrid approach to decentralisation. It attempts to balance Blockchain benefits with some requirements for off-chain processing and storage. For instance, data which is subject to privacy rules may not belong on chain (e.g. personal postal addresses) whilst some documents (e.g. proof of purchase) may suit on chain storage perfectly. + +## Data Layer + +The core business services in the Nethereum.eShop are agnostic of the actual data persistence provider. A mixture of the repository and CQRS patterns are present. The repositories are typically involved in business unit transactions whilst queries are for highly optimised, performance intensive requirements which may require a provider specific implementation or additional resources such as data warehouses, external API's, search services etc. As a basic example, Entity Framework Core can provide a repository layer implementation whilst Dapper can help provide optimised queries which in some organisations remain under DBA control. + +One of the primary reasons for the design was that some entities would be likely to move from one storage solution to another in the near future. Some entities which can't be stored on chain at present may be able to go on chain in the future once specific privacy concerns have been addressed in core Blockchain technology. Abstracting the storage implementation via a repository or query interface will make it easier to move entity storage in the future. + +## Currently Supported Db's + +* Sql Server +* Sqlite +* MySql +* InMemory + +All of these are currently supported with a mixture of Entity Framework core for Repository implementations and Dapper backed Query implementations. + +Non Entity Framework Core providers could be written as neither the repository or query interfaces are dependent on EF and Dapper. + +Entity Framework Core was chosen because: +* it's already widely used by .net developers +* minimal code is required to implement other EF core based providers +* it provides a migration solution (whatever you may think of it!) diff --git a/docs/eShop-Db-Setup.md b/docs/eShop-Db-Setup.md index e3a024f..2e18024 100644 --- a/docs/eShop-Db-Setup.md +++ b/docs/eShop-Db-Setup.md @@ -2,7 +2,7 @@ ## Configuration -Connection strings are loaded from configuration in the following order. Each source will potentially overwrite settings in previous sources. +Connection strings and settings are loaded from configuration in the following order. Each source will potentially overwrite settings in previous sources. * appsettings.json * appsettings.{environment}.json @@ -12,61 +12,98 @@ Connection strings are loaded from configuration in the following order. Each s For access keys and connection strings, user secrets is preferred for the development environment. It ensures they are excluded from source control and are able to differ from one developer to another. +## Supported DB's + +* SqlServer (tested against 15.0.2000.5 (2019), SQL Server Developer Edition running locally) +* Sqlite +* InMemory + ## Initial Db Setup -### Prerequisites -* Access to a SQL Server (tested against 15.0.2000.5 (2019), SQL Server Developer Edition running locally) -* A Connection string which allows a Database to be created on server - * In a windows environment the current windows user would typically be setup as as sysadmin on the SQL Server and the connection strings would use Integrated Security to map the windows user to SQL Server. This avoids setting a password in the connection string. The initial setup involves the migration creating a database so the connection must be for a user with create db access. -* Install the most recent dotnet-ef tool (necessary to create and run migrations) -``` -dotnet tool install --global dotnet-ef --version 3.1.1 -``` +### Options + +* Automatic migration at Startup. + * During startup of the main "Web" app migrations will be applied to create and update the database. + * This can be enabled with the following settings in appsettings.json + * "CatalogApplyMigrationsOnStartup": true, + * "IdentityApplyMigrationsOnStartup": true, + * *Warning* For SQL Server this will may require a user with necessary permissions to create a DB. +* Manually applying SQL Scripts + * You need to create the DB First (e.g. ``` create database EShop ```) then apply the appropriate scripts below to create the schema. + * src\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts + * src\Nethereum.eShop.SqlServer\Identity\Migrations\Scripts + * src\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts + * src\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts ### DB Connections -* CatalogConnection - the main DB containing products, quotes, orders etc + +Database providers are dictated by the ``` CatalogDbProvider ``` and `` AppIdentityDbProvider` ``` settings. + +Supported values are: +* InMemory +* SqlServer +* Sqlite +* MySql + +``` json + "ConnectionStrings": { + "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "IdentityConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", + "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db", + "CatalogConnection_MySql": "server=localhost;database=eShop;user=eShop;password=oDEcHyOmr1ujVIWLBtQp;Allow User Variables=True", + "IdentityConnection_MySql": "server=localhost;database=eShop;user=eShop;password=oDEcHyOmr1ujVIWLBtQp;Allow User Variables=True", + "BlockchainProcessingProgressDb": "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShopWebJobs;" + }, + "CatalogDbProvider": "SqlServer", + "AppIdentityDbProvider": "SqlServer", + "CatalogApplyMigrationsOnStartup": true, + "IdentityApplyMigrationsOnStartup": true +``` + +* CatalogConnection_{DbProvider} - the main DB containing products, quotes, orders etc * This connection is used by both the Web and WebJob projects -* IdentityConnection - authentication DB +* IdentityConnection_{DbProvider} - authentication DB (web login) * Only used by the Web project at present * BlockchainProcessingProgressDb - stores event log processing progress (last processed block number etc) * Only used by the WebJobs project -### Steps - -* Set up user-secrets - - * Main Web Project: - * Right Click the "Web" project and select "Manage User-Secrets", add the settings below and amend as necessary. - * By default the Web project runs with an in-memory database. To use a real database, the "use-in-memory-db" setting must be set to false. - ``` json - { - "use-in-memory-db": false, - "ConnectionStrings": { - "CatalogConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;" - } - } - ``` - * Web Jobs Project: - * Right Click the "Web" project and select "Manage User-Secrets", add the settings below and amend as necessary. - ``` json - { - "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=;AccountKey=;EndpointSuffix=core.windows.net", - "ConnectionStrings": { - "CatalogConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;", - "BlockchainProcessingProgressDb": "Server=;Integrated Security=true;Initial Catalog=eShopWebJobs;" - } - } - ``` -* Ensure the Web Project builds! (essential for running the initial migration) -* Ensure the SQL Server is running -* Ensure the database you require HAS NOT already been created -* Run a script to create the DB - * In a command prompt - navigate to the root of the "Web" Project - * Run ApplyDbMigrations.bat - * This will create the DB and the necessary tables for the Catalog and Identity - * The "BlockchainProcessingProgressDb" referenced by the WebJobs project is setup differently, it is setup at run-time and created if it does not exist - * Run the Web project to ensure it works as expected +Connection strings names are suffixed with the provider name (e.g. CatalogConnection_SqlServer) to allow easy switching between providers. The developer can multiple connection strings in settings and swap over using only the "CatalogDbProvider" and "AppIdentityDbProvider" settings. + +### User Secrets + +The "Web" and "WebJobs" project share the same User Secrets Id. This is because they are expected to share the same persistence stores. To set or change user secrets, right click the project and select "manage user-secrets". + +### Adding Migrations and DB Creation Scripts + +When schema changes have been made, migrations should be created so that DB's can be created or updated to the most recent schema. + +The solution is setup so that migrations for multiple DB providers can be managed from one place which ensures they are in sync. Note: creating or adding a migration does not update the database, it simply creates code or scripts which can be run later. +Migrations are created using the "dotnet-ef" tool with a specific start up project ('Nethereum.eShop.Migrations'). The migration process requires a start up project and it is not practical to use the main "Web" or "WebApp" projects as these are only configured for one Db provider at any one time. The goal here is to create migrations for each DB provider at once. + +* Installing dotnet-ef tool (you may need to update to .Net Core 3.1.2 first) +``` +dotnet tool install --global dotnet-ef --version 3.1.2 +``` + +#### Adding a migration + +Batch files which create a named migration for Catalog and Identity for all supported Db Providers. + +``` +AddCatalogMigration.bat +AddIdentityMigration.bat +``` + +Creates a new migration in each DB provider project. + +#### Creating Db Scripts + +Generates a complete DB creation script for each supported Db Provider for both the Catalog connection and Identity connection. This script can be run manually against the chosen database. + +``` +ScriptCatalogDb.bat +ScriptIdentityDb.bat +``` diff --git a/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs new file mode 100644 index 0000000..35c2d96 --- /dev/null +++ b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.Configuration; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.InMemory.Catalog; +using Nethereum.eShop.InMemory.Infrastructure.Identity; +using Nethereum.eShop.MySql.Catalog; +using Nethereum.eShop.MySql.Identity; +using Nethereum.eShop.Sqlite.Catalog; +using Nethereum.eShop.Sqlite.Identity; +using Nethereum.eShop.SqlServer.Catalog; +using Nethereum.eShop.SqlServer.Identity; + +namespace Nethereum.eShop.DbFactory +{ + public static class EShopDbBootstrapper + { + public static IEShopDbBootstrapper CreateInMemoryDbBootstrapper() => new InMemoryEShopDbBootrapper(); + public static IEShopIdentityDbBootstrapper CreateInMemoryAppIdentityDbBootstrapper() => new InMemoryEShopAppIdentityDbBootrapper(); + + public static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) + { + var name = configuration["CatalogDbProvider"]?.ToLower(); + return name switch + { + "sqlserver" => new SqlServerEShopDbBootstrapper(), + "sqlite" => new SqliteEShopDbBootstrapper(), + "mysql" => new MySqlEShopDbBootstrapper(), + _ => new InMemoryEShopDbBootrapper() + }; + } + + public static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) + { + var name = configuration["AppIdentityDbProvider"]?.ToLower(); + return name switch + { + "sqlserver" => new SqlServerEShopAppIdentityDbBootstrapper(), + "sqlite" => new SqliteEShopAppIdentityDbBootstrapper(), + "mysql" => new MySqlEShopAppIdentityDbBootstrapper(), + _ => new InMemoryEShopAppIdentityDbBootrapper() + }; + } + } +} diff --git a/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj b/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj new file mode 100644 index 0000000..afd993f --- /dev/null +++ b/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.1 + + + + + + + + + + diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs new file mode 100644 index 0000000..62a3ee3 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs @@ -0,0 +1,23 @@ +using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Cache; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog.Cache +{ + public class RuleTreeCache : GeneralCache, IRuleTreeCache + { + public RuleTreeCache() + {} + + public Task GetByIdAsync(string id) + { + return Task.FromResult(new RuleTree(new RuleTreeSeed())); + } + + public Task GetLastRuleTreeCreatedAsync() + { + return Task.FromResult(new RuleTree(new RuleTreeSeed())); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs b/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs new file mode 100644 index 0000000..e827893 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs @@ -0,0 +1,115 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System; +using System.Data; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog +{ + public class CatalogContext : DbContext, IUnitOfWork + { + private readonly IMediator _mediator; + private IDbContextTransaction _currentTransaction; + + public CatalogContext( + DbContextOptions options, IMediator mediator) : base(options) + { + _mediator = mediator; + } + + public DbSet Buyers { get; set; } + public DbSet Baskets { get; set; } + public DbSet BasketItems { get; set; } + public DbSet CatalogItems { get; set; } + public DbSet CatalogBrands { get; set; } + public DbSet CatalogTypes { get; set; } + public DbSet StockItems { get; set; } + public DbSet Quotes { get; set; } + public DbSet QuoteItems { get; set; } + public DbSet Orders { get; set; } + public DbSet OrderItems { get; set; } + + public DbSet Settings { get; set; } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + } + + public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + // Dispatch Domain Events collection. + // Choices: + // A) Right BEFORE committing data (EF SaveChanges) into the DB will make a single transaction including + // side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime + // B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions. + // You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers. + await _mediator.DispatchDomainEventsAsync(this).ConfigureAwait(false); + + // After executing this line all the changes (from the Command Handler and Domain Event Handlers) + // performed through the DbContext will be committed + var result = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + + return true; + } + + public async Task BeginTransactionAsync() + { + if (_currentTransaction != null) return null; + + _currentTransaction = await Database.BeginTransactionAsync(IsolationLevel.ReadCommitted).ConfigureAwait(false); + + return _currentTransaction; + } + + public async Task CommitTransactionAsync(IDbContextTransaction transaction) + { + if (transaction == null) throw new ArgumentNullException(nameof(transaction)); + if (transaction != _currentTransaction) throw new InvalidOperationException($"Transaction {transaction.TransactionId} is not current"); + + try + { + await SaveChangesAsync().ConfigureAwait(false); + transaction.Commit(); + } + catch + { + RollbackTransaction(); + throw; + } + finally + { + if (_currentTransaction != null) + { + _currentTransaction.Dispose(); + _currentTransaction = null; + } + } + } + + public void RollbackTransaction() + { + try + { + _currentTransaction?.Rollback(); + } + finally + { + if (_currentTransaction != null) + { + _currentTransaction.Dispose(); + _currentTransaction = null; + } + } + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs new file mode 100644 index 0000000..9c384ad --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs @@ -0,0 +1,58 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Catalog.Cache; +using Nethereum.eShop.EntityFramework.Catalog.Repositories; +using Nethereum.eShop.EntityFramework.Catalog.Seed; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog +{ + public abstract class EShopDbBootstrapperBase + { + public virtual void AddRepositories(IServiceCollection services, IConfiguration configuration) + { + services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + } + + public virtual void AddSeeders(IServiceCollection services, IConfiguration configuration) + { + var CatalogSeedJsonFile = configuration["CatalogSeedJsonFile"]; + + if (string.IsNullOrEmpty(CatalogSeedJsonFile)) + { + services.AddScoped(); + } + else + { + services.AddScoped(); + } + } + + public virtual Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) + { + if (ApplyMigrationsOnStartup(configuration)) + { + var context = serviceProvider.GetRequiredService(); + return context.Database.MigrateAsync(cancellationToken); + } + return Task.CompletedTask; + } + + protected virtual bool ApplyMigrationsOnStartup(IConfiguration configuration) + { + return configuration.GetValue("CatalogApplyMigrationsOnStartup", false); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketConfiguration.cs similarity index 68% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketConfiguration.cs index 3062c19..958f374 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketConfiguration.cs @@ -2,11 +2,11 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BasketConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Basket.Items)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); @@ -19,18 +19,13 @@ public void Configure(EntityTypeBuilder builder) .HasMaxLength(256) .IsRequired(); - builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); + builder.Property(b => b.TransactionHash).IsHash(); + builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); + builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); - builder.OwnsOne(o => o.ShipTo, a => - { - a.ConfigureAddress(); - }); - builder.OwnsOne(o => o.BillTo, a => - { - a.ConfigureAddress(); - }); + builder.HasIndex(b => b.BuyerId); + builder.HasIndex(b => b.BuyerAddress); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketItemConfiguration.cs similarity index 73% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BasketItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketItemConfiguration.cs index ddbddbc..6ade3fe 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketItemConfiguration.cs @@ -2,11 +2,11 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BasketItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.Property(bi => bi.UnitPrice) .IsRequired(true) diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BuyerConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs similarity index 71% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BuyerConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs index 556e964..2a6b02b 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/BuyerConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs @@ -2,20 +2,22 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BuyerConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Buyer.PostalAddresses)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); builder.Property(b => b.BuyerId).HasMaxLength(256).IsRequired(); builder.Property(b => b.BuyerAddress).IsAddress(); + builder.Property(b => b.BuyerWalletAddress).IsAddress(); builder.HasIndex(b => b.BuyerId).IsUnique(); builder.HasIndex(b => b.BuyerAddress).IsUnique(); + builder.HasIndex(b => b.BuyerWalletAddress).IsUnique(); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs similarity index 53% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs index 13e5ec9..abb3fed 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs @@ -2,16 +2,13 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BuyerPostalAddressConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { - builder.OwnsOne(o => o.PostalAddress, a => - { - a.ConfigureAddress(); - }); + builder.OwnsOne(o => o.PostalAddress, a => a.ConfigureAddress()); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogBrandConfiguration.cs similarity index 74% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogBrandConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogBrandConfiguration.cs index a167a52..d0d9b1b 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogBrandConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogBrandConfiguration.cs @@ -2,16 +2,15 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class CatalogBrandConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.HasKey(ci => ci.Id); builder.Property(ci => ci.Id) - .UseHiLo("catalog_brand_hilo") .IsRequired(); builder.Property(cb => cb.Brand) diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemConfiguration.cs similarity index 68% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemConfiguration.cs index a4fe342..19faf22 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemConfiguration.cs @@ -2,16 +2,15 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class CatalogItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.ToTable("Catalog"); builder.Property(ci => ci.Id) - .UseHiLo("catalog_hilo") .IsRequired(); builder.Property(ci => ci.Name) @@ -27,6 +26,19 @@ public void Configure(EntityTypeBuilder builder) .IsPrice(); builder.Property(ci => ci.PictureUri) + .IsUri() + .IsRequired(false); + + builder.Property(ci => ci.PictureSmallUri) + .IsUri() + .IsRequired(false); + + builder.Property(ci => ci.PictureMediumUri) + .IsUri() + .IsRequired(false); + + builder.Property(ci => ci.PictureLargeUri) + .IsUri() .IsRequired(false); builder.HasOne(ci => ci.CatalogBrand) diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemExcerptBuilder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemExcerptBuilder.cs new file mode 100644 index 0000000..dc97e3a --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemExcerptBuilder.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; + +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders +{ + public static class CatalogItemExcerptBuilder + { + public static void ConfigureCatalogItemExcerpt(this OwnedNavigationBuilder a) where TParentEntity : class{ + + a.WithOwner(); + + a.Property(cio => cio.ProductName) + .HasMaxLength(50) + .IsRequired(); + + a.Property(cio => cio.PictureUri).IsUri(); + + a.Property(cio => cio.Gtin).IsGtin(); + } + + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogTypeConfiguration.cs new file mode 100644 index 0000000..0a554fd --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogTypeConfiguration.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; + +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders +{ + public class CatalogTypeConfiguration : IEntityTypeConfiguration + { + public virtual void Configure(EntityTypeBuilder builder) + { + builder.HasKey(ci => ci.Id); + + builder.Property(ci => ci.Id) + .IsRequired(); + + builder.Property(cb => cb.Type) + .IsRequired() + .HasMaxLength(100); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/EntityBuilderExtensions.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/EntityBuilderExtensions.cs new file mode 100644 index 0000000..e7303b1 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/EntityBuilderExtensions.cs @@ -0,0 +1,50 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders +{ + public static class EntityBuilderExtensions + { + private const int HashLength = 67; + private const int AddressLength = 43; + private const int BigIntegerLength = 100; + private const int Bytes32Length = 32; + private const int UriLength = 512; + private const int GtinLength = 14; + + public static PropertyBuilder IsPrice(this PropertyBuilder prop) + { + return prop.HasColumnType("decimal(18,2)"); + } + + public static PropertyBuilder IsHash(this PropertyBuilder prop) + { + return prop.HasMaxLength(HashLength); + } + + public static PropertyBuilder IsAddress(this PropertyBuilder prop) + { + return prop.HasMaxLength(AddressLength); + } + + public static PropertyBuilder IsBigInteger(this PropertyBuilder prop) + { + return prop.HasMaxLength(BigIntegerLength); + } + + public static PropertyBuilder IsBytes32(this PropertyBuilder prop) + { + return prop.HasMaxLength(Bytes32Length); + } + + public static PropertyBuilder IsUri(this PropertyBuilder prop) + { + return prop.HasMaxLength(UriLength); + } + + public static PropertyBuilder IsGtin(this PropertyBuilder prop) + { + return prop.HasMaxLength(GtinLength); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs similarity index 54% rename from src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs index 39f48d6..06d4657 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs @@ -1,36 +1,27 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class OrderConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Order.OrderItems)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); - - builder.OwnsOne(o => o.ShipTo, a => - { - a.ConfigureAddress(); - }); - - builder.OwnsOne(o => o.BillTo, a => - { - a.ConfigureAddress(); - }); - + builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); + builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); builder.Property(o => o.BuyerId).HasMaxLength(256).IsRequired(); - builder.Property(o => o.BuyerAddress).IsAddress(); - builder.Property(o => o.ApproverAddress).IsAddress(); builder.Property(o => o.BuyerWalletAddress).IsAddress(); builder.Property(o => o.TransactionHash).IsHash(); + builder.Property(o => o.CurrencyAddress).IsAddress(); + builder.Property(o => o.CurrencySymbol).IsBytes32(); + builder.Property(o => o.SellerId).IsBytes32(); + + builder.HasIndex(b => b.BuyerId); } } } diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderItemConfiguration.cs new file mode 100644 index 0000000..0b1ff81 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderItemConfiguration.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; + +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders +{ + public class OrderItemConfiguration : IEntityTypeConfiguration + { + public virtual void Configure(EntityTypeBuilder builder) + { + builder.OwnsOne(i => i.ItemOrdered, io => io.ConfigureCatalogItemExcerpt()); + + builder.Property(oi => oi.UnitPrice) + .IsRequired(true) + .IsPrice(); + + builder.Property(i => i.Unit).HasMaxLength(50); + builder.Property(i => i.QuantityAddress).IsAddress(); + builder.Property(i => i.QuantitySymbol).IsBytes32(); + builder.Property(i => i.CurrencyValue).IsBigInteger(); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/PostalAddressBuilder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/PostalAddressBuilder.cs similarity index 88% rename from src/Nethereum.eShop/Infrastructure/Data/Config/PostalAddressBuilder.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/PostalAddressBuilder.cs index 11f28e3..cde1ecf 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/PostalAddressBuilder.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/PostalAddressBuilder.cs @@ -1,10 +1,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -using System; -using System.Collections.Generic; -using System.Text; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public static class PostalAddressBuilder { diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteConfiguration.cs similarity index 64% rename from src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteConfiguration.cs index 07b0576..04844dc 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteConfiguration.cs @@ -2,34 +2,28 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class QuoteConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Quote.QuoteItems)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); - - builder.OwnsOne(o => o.ShipTo, a => - { - a.ConfigureAddress(); - }); - - builder.OwnsOne(o => o.BillTo, a => - { - a.ConfigureAddress(); - }); - + builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); + builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); builder.Property(o => o.BuyerId).HasMaxLength(256).IsRequired(); builder.Property(o => o.BuyerAddress).IsAddress(); builder.Property(o => o.ApproverAddress).IsAddress(); builder.Property(o => o.BuyerWalletAddress).IsAddress(); builder.Property(o => o.TransactionHash).IsHash(); + builder.Property(o => o.CurrencyAddress).IsAddress(); + builder.Property(o => o.CurrencySymbol).IsBytes32(); + builder.Property(o => o.SellerId).IsBytes32(); + builder.HasIndex(b => b.BuyerId); + builder.HasIndex(b => b.BuyerAddress); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteItemConfiguration.cs similarity index 51% rename from src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteItemConfiguration.cs index b289a40..5adeab5 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteItemConfiguration.cs @@ -2,20 +2,13 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class QuoteItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { - builder.OwnsOne(i => i.ItemOrdered, io => - { - io.WithOwner(); - - io.Property(cio => cio.ProductName) - .HasMaxLength(50) - .IsRequired(); - }); + builder.OwnsOne(i => i.ItemOrdered, io => io.ConfigureCatalogItemExcerpt()); builder.Property(oi => oi.UnitPrice) .IsPrice() diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs new file mode 100644 index 0000000..5fb9bad --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; + +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders +{ + public class SettingConfiguration : IEntityTypeConfiguration + { + public virtual void Configure(EntityTypeBuilder builder) + { + builder.Property(b => b.Key).HasMaxLength(100); + builder.Property(b => b.Value); + + builder.HasIndex(b => b.Key); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/StockItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/StockItemConfiguration.cs similarity index 79% rename from src/Nethereum.eShop/Infrastructure/Data/Config/StockItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/StockItemConfiguration.cs index 413189f..9bb531a 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/StockItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/StockItemConfiguration.cs @@ -2,16 +2,15 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class StockItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.ToTable("Stock"); builder.Property(ci => ci.Id) - .UseHiLo("stock_hilo") .IsRequired(); builder.Property(ci => ci.Location) diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/MediatorExtension.cs b/src/Nethereum.eShop.EntityFramework/Catalog/MediatorExtension.cs new file mode 100644 index 0000000..597b045 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/MediatorExtension.cs @@ -0,0 +1,28 @@ +using MediatR; +using Nethereum.eShop.ApplicationCore.Entities; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog +{ + public static class MediatorExtension + { + public static async Task DispatchDomainEventsAsync(this IMediator mediator, CatalogContext ctx) + { + var domainEntities = ctx.ChangeTracker + .Entries() + .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()); + + var domainEvents = domainEntities + .SelectMany(x => x.Entity.DomainEvents) + .ToList(); + + domainEntities.ToList() + .ForEach(entity => entity.Entity.ClearDomainEvents()); + + foreach (var domainEvent in domainEvents) + await mediator.Publish(domainEvent); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/BasketRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/BasketRepository.cs new file mode 100644 index 0000000..9417881 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/BasketRepository.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories +{ + public class BasketRepository : EfRepository, IBasketRepository + { + public BasketRepository(CatalogContext dbContext) : base(dbContext) { } + + public Task GetByIdWithItemsAsync(int id) => + _dbContext.Baskets + .Include(b => b.Items) + .Where(b => b.Id == id) + .FirstOrDefaultAsync(); + + public Task GetByBuyerIdWithItemsAsync(string buyerId) => + _dbContext.Baskets + .Include(b => b.Items) + .Where(b => b.BuyerId == buyerId) + .FirstOrDefaultAsync(); + + public void Delete(int basketId) + { + _dbContext.Entry(Basket.CreateForDeletion(basketId)).State = EntityState.Deleted; + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/CatalogItemRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/CatalogItemRepository.cs new file mode 100644 index 0000000..f2cf728 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/CatalogItemRepository.cs @@ -0,0 +1,10 @@ +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Interfaces; + +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories +{ + public class CatalogItemRepository : EfRepository, ICatalogItemRepository + { + public CatalogItemRepository(CatalogContext dbContext) : base(dbContext){} + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/EfRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/EfRepository.cs new file mode 100644 index 0000000..0c049aa --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/EfRepository.cs @@ -0,0 +1,46 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Data; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories +{ + public class EfRepository : IAsyncRepository where T : BaseEntity, IAggregateRoot + { + protected readonly CatalogContext _dbContext; + + public virtual IUnitOfWork UnitOfWork => _dbContext; + + public EfRepository(CatalogContext dbContext) + { + _dbContext = dbContext; + } + + public virtual async Task GetByIdAsync(int id) + { + return await _dbContext.Set().FindAsync(id).ConfigureAwait(false); + } + + public virtual async Task> ListAllAsync() + { + return await _dbContext.Set().ToListAsync().ConfigureAwait(false); + } + + public virtual async Task> ListAsync(ISpecification spec) + { + return await ApplySpecification(spec).ToListAsync().ConfigureAwait(false); + } + + private IQueryable ApplySpecification(ISpecification spec) + { + return SpecificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), spec); + } + + public virtual T Add(T entity) => _dbContext.Set().Add(entity).Entity; + public virtual T Update(T entity) => _dbContext.Set().Update(entity).Entity; + public virtual void Delete(T entity) => _dbContext.Set().Remove(entity); + } +} \ No newline at end of file diff --git a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs similarity index 91% rename from src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs index 396d427..f37f9d8 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs @@ -3,8 +3,9 @@ using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { + public class OrderRepository : EfRepository, IOrderRepository { public OrderRepository(CatalogContext dbContext) : base(dbContext) diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/QuoteRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/QuoteRepository.cs new file mode 100644 index 0000000..02c8766 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/QuoteRepository.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories +{ + public class QuoteRepository : EfRepository, IQuoteRepository + { + public QuoteRepository(CatalogContext dbContext) : base(dbContext){} + + public Task GetByIdWithItemsAsync(int id) => + _dbContext.Quotes + .Include(b => b.QuoteItems) + .Where(b => b.Id == id) + .FirstOrDefaultAsync(); + + public Task> GetQuotesRequiringPurchaseOrderAsync() => + _dbContext.Quotes.Where(quote => quote.Status == QuoteStatus.Pending && quote.PoNumber == null) + .Include(q => q.QuoteItems) + .ToListAsync(); + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/ReportRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/ReportRepository.cs similarity index 68% rename from src/Nethereum.eShop/Infrastructure/Data/ReportRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/ReportRepository.cs index 0eb092e..fd38fc3 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/ReportRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/ReportRepository.cs @@ -1,10 +1,9 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; +using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; using Nethereum.eShop.ApplicationCore.Interfaces; using System.Collections.Generic; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { // NOTE: To be determined where reports will be stored in the database, if at all - // We may either need to 1.) alter EFRepository so that it has a DBContext supporting @@ -15,9 +14,9 @@ public ReportRepository(CatalogContext dbContext) : base(dbContext) { } - public async Task> GetByRuleTreeIdAsync(int ruleTreeId) + public Task> GetByRuleTreeIdAsync(int ruleTreeId) { - return new List(); + return Task.FromResult(new List()); } } } \ No newline at end of file diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs new file mode 100644 index 0000000..aed0303 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs @@ -0,0 +1,28 @@ +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories +{ + public class SettingRepository : EfRepository, ISettingRepository + { + public SettingRepository(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task GetEShopConfigurationSettingsAsync() + { + var settings = await ListAllAsync().ConfigureAwait(false); + return new EShopConfigurationSettings(settings); + } + + public async Task UpdateAsync(EShopConfigurationSettings configurationSettings) + { + var settings = await ListAllAsync().ConfigureAwait(false); + var list = settings.ToList(); + configurationSettings.UpdateSettings(list); + _dbContext.UpdateRange(list); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/StockItemRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/StockItemRepository.cs similarity index 82% rename from src/Nethereum.eShop/Infrastructure/Data/StockItemRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/StockItemRepository.cs index 7b6d2d0..0be086b 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/StockItemRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/StockItemRepository.cs @@ -1,7 +1,7 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class StockItemRepository : EfRepository, IStockItemRepository { diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContextSeed.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogContextSeed.cs similarity index 92% rename from src/Nethereum.eShop/Infrastructure/Data/CatalogContextSeed.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogContextSeed.cs index 6b005aa..09aabad 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContextSeed.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogContextSeed.cs @@ -1,17 +1,23 @@ using Microsoft.Extensions.Logging; using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Interfaces; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Seed { public class HardCodedCatalogContextSeeder: ICatalogContextSeeder { - public async Task SeedAsync(CatalogContext catalogContext, - ILoggerFactory loggerFactory, int? retry = 0) + private readonly CatalogContext catalogContext; + public HardCodedCatalogContextSeeder(CatalogContext catalogContext) + { + this.catalogContext = catalogContext; + } + + public async Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0) { int retryForAvailability = retry.Value; try @@ -50,7 +56,7 @@ public async Task SeedAsync(CatalogContext catalogContext, retryForAvailability++; var log = loggerFactory.CreateLogger(); log.LogError(ex.Message); - await SeedAsync(catalogContext, loggerFactory, retryForAvailability); + await SeedAsync(loggerFactory, retryForAvailability); } } } diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs new file mode 100644 index 0000000..f14f457 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs @@ -0,0 +1,39 @@ +using Nethereum.eShop.ApplicationCore.Entities; +using System.Collections.Generic; + +namespace Nethereum.eShop.EntityFramework.Catalog.Seed +{ + public class CatalogImportDto + { + public List CatalogBrands { get; set; } = new List(); + public List CatalogTypes { get; set; } = new List(); + public List CatalogItems { get; set; } = new List(); + } + + public class CatalogBrandForImport : CatalogBrand + { + public new int Id + { + get => base.Id; + set => base.Id = value; + } + } + + public class CatalogTypeForImport : CatalogType + { + public new int Id + { + get => base.Id; + set => base.Id = value; + } + } + + public class CatalogItemForImport : CatalogItem + { + public new int Id + { + get => base.Id; + set => base.Id = value; + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/JsonCatalogContextSeeder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs similarity index 81% rename from src/Nethereum.eShop/Infrastructure/Data/JsonCatalogContextSeeder.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs index fb1f079..30f2ea4 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/JsonCatalogContextSeeder.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs @@ -1,20 +1,23 @@ using Microsoft.Extensions.Logging; +using Nethereum.eShop.ApplicationCore.Interfaces; using Newtonsoft.Json; using System; using System.IO; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Seed { public class JsonCatalogContextSeeder : ICatalogContextSeeder { private readonly string _productImportJsonFile; + private readonly CatalogContext catalogContext; - public JsonCatalogContextSeeder(string productImportJsonFile) + public JsonCatalogContextSeeder(CatalogSettings catalogSettings, CatalogContext catalogContext) { - this._productImportJsonFile = productImportJsonFile; + this.catalogContext = catalogContext; + _productImportJsonFile = catalogSettings.CatalogSeedJsonFile; } private CatalogImportDto GetImportDataFromJsonFile() @@ -30,7 +33,7 @@ private CatalogImportDto GetImportDataFromJsonFile() } } - public async Task SeedAsync(CatalogContext catalogContext, ILoggerFactory loggerFactory, int? retry = 0) + public async Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0) { int retryForAvailability = retry.Value; @@ -46,6 +49,8 @@ public async Task SeedAsync(CatalogContext catalogContext, ILoggerFactory logger // if we are not running an in memory db - we may need allow id's to be inserted intead of auto generated // context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Students ON"); + var dictionary = importData.CatalogBrands.ToDictionary(b => b.Brand, b => b.Id); + if (!catalogContext.CatalogBrands.Any()) { catalogContext.CatalogBrands.AddRange( @@ -77,7 +82,7 @@ public async Task SeedAsync(CatalogContext catalogContext, ILoggerFactory logger retryForAvailability++; var log = loggerFactory.CreateLogger(); log.LogError(ex.Message); - await SeedAsync(catalogContext, loggerFactory, retryForAvailability); + await SeedAsync(loggerFactory, retryForAvailability); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/SpecificationEvaluator.cs b/src/Nethereum.eShop.EntityFramework/Common/Repositories/SpecificationEvaluator.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/SpecificationEvaluator.cs rename to src/Nethereum.eShop.EntityFramework/Common/Repositories/SpecificationEvaluator.cs diff --git a/src/Nethereum.eShop/Infrastructure/Identity/AppIdentityDbContext.cs b/src/Nethereum.eShop.EntityFramework/Identity/AppIdentityDbContext.cs similarity index 79% rename from src/Nethereum.eShop/Infrastructure/Identity/AppIdentityDbContext.cs rename to src/Nethereum.eShop.EntityFramework/Identity/AppIdentityDbContext.cs index 4da6439..51a883f 100644 --- a/src/Nethereum.eShop/Infrastructure/Identity/AppIdentityDbContext.cs +++ b/src/Nethereum.eShop.EntityFramework/Identity/AppIdentityDbContext.cs @@ -1,12 +1,12 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.Infrastructure.Identity; - -namespace Nethereum.eShop.Infrastructure.Identity +namespace Nethereum.eShop.EntityFramework.Identity { public class AppIdentityDbContext : IdentityDbContext { - public AppIdentityDbContext(DbContextOptions options) + public AppIdentityDbContext(DbContextOptions options) : base(options) { } diff --git a/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs new file mode 100644 index 0000000..f56e95a --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs @@ -0,0 +1,36 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.Infrastructure.Identity; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Identity +{ + public abstract class EShopAppIdentityDbBootstrapperBase + { + public virtual Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) + { + if (ApplyMigrationsOnStartup(configuration)) + { + var context = serviceProvider.GetRequiredService(); + return context.Database.MigrateAsync(cancellationToken); + } + return Task.CompletedTask; + } + + protected virtual bool ApplyMigrationsOnStartup(IConfiguration configuration) + { + return configuration.GetValue("IdentityApplyMigrationsOnStartup", false); + } + + public virtual void AddIdentityStores(IdentityBuilder identityBuilder, IServiceCollection services) + { + identityBuilder.AddEntityFrameworkStores(); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj b/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj new file mode 100644 index 0000000..63e48af --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj @@ -0,0 +1,27 @@ + + + + netstandard2.1 + 80b8bc7f-cc13-45f4-967c-6c2b164a22e3 + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs b/src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs new file mode 100644 index 0000000..07a7091 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs @@ -0,0 +1,21 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.InMemory.Catalog +{ + public class InMemoryCatalogContext : CatalogContext + { + public InMemoryCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + //config is in EntityFramework project + builder.ApplyConfigurationsFromAssembly(typeof(CatalogContext).Assembly); + } + } +} + diff --git a/src/Nethereum.eShop.InMemory/Catalog/InMemoryEShopDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Catalog/InMemoryEShopDbBootrapper.cs new file mode 100644 index 0000000..ec229c9 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/InMemoryEShopDbBootrapper.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.InMemory.Catalog.Queries; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.Catalog +{ + public class InMemoryEShopDbBootrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(c => + c.UseInMemoryDatabase("Catalog")); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + } + + public override Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) => Task.CompletedTask; + } +} diff --git a/src/Nethereum.eShop.InMemory/Catalog/Queries/CatalogQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/CatalogQueries.cs new file mode 100644 index 0000000..47674ed --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/CatalogQueries.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.EntityFramework.Catalog; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.Catalog.Queries +{ + public class CatalogQueries : QueriesBase, ICatalogQueries + { + public CatalogQueries(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + var query = Where(catalogQuerySpecification).AsNoTracking(); + + var totalCount = await query.CountAsync(); + + var items = await query + .Skip(catalogQuerySpecification.Offset) + .Take(catalogQuerySpecification.Fetch) + .Select(i => + new CatalogExcerpt + { + Id = i.Id, + Brand = i.CatalogBrand.Brand, + Name = i.Name, + PictureUri = i.PictureUri, + Price = i.Price + }) + .ToListAsync(); + + return new PaginatedResult(totalCount, items, catalogQuerySpecification); + } + + private IQueryable Where(GetCatalogItemsSpecification spec) + { + var query = _dbContext.CatalogItems + .Include(c => c.CatalogBrand) + .Where(c => + (string.IsNullOrEmpty(spec.SearchText) || (c.Name.Contains(spec.SearchText, StringComparison.OrdinalIgnoreCase) || c.CatalogBrand.Brand.Contains(spec.SearchText, StringComparison.OrdinalIgnoreCase))) && + (spec.BrandId == null || (c.CatalogBrandId == spec.BrandId)) && + (spec.TypeId == null || (c.CatalogTypeId == spec.TypeId)) + ); + + //TODO: implement other sort columns + switch (spec.SortBy) + { + default: + return spec.SortDescending ? query.OrderByDescending(c => c.Rank) : query.OrderBy(c => c.Rank); + } + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs new file mode 100644 index 0000000..affb0cc --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs @@ -0,0 +1,63 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.EntityFramework.Catalog; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.Catalog.Queries +{ + public class OrderQueries : QueriesBase, IOrderQueries + { + public OrderQueries(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + var query = Where(buyerId, paginationArgs).AsNoTracking(); + + var totalCount = await query.CountAsync(); + + var items = await query. + // Include(o => o.OrderItems). + Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}") + .Skip(paginationArgs.Offset) + .Take(paginationArgs.Fetch) + .Select(o => new OrderExcerpt + { + BillTo_RecipientName = o.BillTo.RecipientName, + BillTo_ZipCode = o.BillTo.ZipCode, + BuyerId = o.BuyerId, + CurrencySymbol = o.CurrencySymbol, + ItemCount = o.ItemCount(), + OrderDate = o.OrderDate, + OrderId = o.Id, + PoNumber = o.PoNumber.ToString(), + PoType = o.PoType.ToString(), + QuoteId = o.QuoteId ?? 0, + ShipTo_RecipientName = o.ShipTo.RecipientName, + ShipTo_ZipCode = o.ShipTo.ZipCode, + Status = o.Status.ToString(), + Total = o.Total(), + TransactionHash = o.TransactionHash + }) + .ToListAsync(); + + return new PaginatedResult(totalCount, items, paginationArgs); + } + + private IQueryable Where(string buyerId, PaginationArgs paginationArgs) + { + var query = _dbContext.Orders.Where(o => o.BuyerId == buyerId); + + //TODO: implement other sort columns + switch (paginationArgs.SortBy) + { + default: + return paginationArgs.SortDescending ? query.OrderByDescending(c => c.Id) : query.OrderBy(c => c.Id); + } + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Catalog/Queries/QueriesBase.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/QueriesBase.cs new file mode 100644 index 0000000..f0879c2 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/QueriesBase.cs @@ -0,0 +1,14 @@ +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.InMemory.Catalog.Queries +{ + public abstract class QueriesBase + { + protected readonly CatalogContext _dbContext; + + public QueriesBase(CatalogContext dbContext) + { + _dbContext = dbContext; + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Catalog/Queries/QuoteQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/QuoteQueries.cs new file mode 100644 index 0000000..0baed72 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/QuoteQueries.cs @@ -0,0 +1,63 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.Catalog.Queries +{ + public class QuoteQueries : QueriesBase, IQuoteQueries + { + public QuoteQueries(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + var query = Where(buyerId, paginationArgs).AsNoTracking(); + + var totalCount = await query.CountAsync(); + + var items = await query. + Include(o => o.QuoteItems) + .Skip(paginationArgs.Offset) + .Take(paginationArgs.Fetch) + .Select(o => new QuoteExcerpt + { + BillTo_RecipientName = o.BillTo.RecipientName, + BillTo_ZipCode = o.BillTo.ZipCode, + BuyerAddress = o.BuyerAddress, + BuyerId = o.BuyerId, + CurrencySymbol = o.CurrencySymbol, + ItemCount = o.ItemCount(), + QuoteDate = o.Date, + QuoteId = o.Id, + PoNumber = o.PoNumber.ToString(), + PoType = o.PoType.ToString(), + Expiry = o.Expiry, + ShipTo_RecipientName = o.ShipTo.RecipientName, + ShipTo_ZipCode = o.ShipTo.ZipCode, + Status = o.Status.ToString(), + Total = o.Total(), + TransactionHash = o.TransactionHash + }) + .ToListAsync(); + + return new PaginatedResult(totalCount, items, paginationArgs); + } + + private IQueryable Where(string buyerId, PaginationArgs paginationArgs) + { + var query = _dbContext.Quotes.Where(o => o.BuyerId == buyerId); + + //TODO: implement other sort columns + switch (paginationArgs.SortBy) + { + default: + return paginationArgs.SortDescending ? query.OrderByDescending(c => c.Id) : query.OrderBy(c => c.Id); + } + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs new file mode 100644 index 0000000..8d58229 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.Infrastructure.Identity +{ + public class InMemoryEShopAppIdentityDbBootrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Identity")); + } + + public override Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) => Task.CompletedTask; + } +} diff --git a/src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs b/src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs new file mode 100644 index 0000000..ca2a030 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.InMemory.Infrastructure.Identity +{ + public class InMemoryAppIdentityDbContext : AppIdentityDbContext + { + public InMemoryAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj new file mode 100644 index 0000000..ece7edc --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.1 + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat b/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat new file mode 100644 index 0000000..38a859b --- /dev/null +++ b/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat @@ -0,0 +1,3 @@ +dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Catalog\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output-dir ..\Nethereum.eShop.Sqlite\Catalog\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output-dir ..\Nethereum.eShop.MySql\Catalog\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat b/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat new file mode 100644 index 0000000..2ce8910 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat @@ -0,0 +1,3 @@ +dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output-dir ..\Nethereum.eShop.SqlServer\Identity\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output-dir ..\Nethereum.eShop.Sqlite\Identity\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output-dir ..\Nethereum.eShop.MySql\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj b/src/Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj new file mode 100644 index 0000000..fdcfd73 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj @@ -0,0 +1,19 @@ + + + + Exe + netcoreapp3.1 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/src/Nethereum.eShop.Migrations/Program.cs b/src/Nethereum.eShop.Migrations/Program.cs new file mode 100644 index 0000000..5f9c882 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/Program.cs @@ -0,0 +1,22 @@ +using System; + +namespace Nethereum.eShop.Migrations +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("IMPORTANT!"); + Console.WriteLine("This 'Nethereum.eShop.Migrations' console is only for generating Entity Framework Migrations"); + Console.WriteLine("It is ONLY intended to be run as the startup project for the dotnet-ef tool to add a migration or create a script"); + Console.WriteLine(); + Console.WriteLine("To add a named migration - go to the command line and run either AddCatalogMigration.bat or AddIdentityMigratoin.bat and supply the name of the migration"); + Console.WriteLine("This will create migrations for each DB provider (e.g. SqlServer, Sqlite, MySql etc)"); + Console.WriteLine(" e.g. AddCatalogMigration.bat InitialCreate"); + Console.ReadLine(); + Console.WriteLine("To create SQL Scripts for DB Creation or Update"); + Console.WriteLine(" e.g. ScriptCatalogDbs.bat or ScriptIdentityDb.bat"); + Console.ReadLine(); + } + } +} diff --git a/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat b/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat new file mode 100644 index 0000000..e7317f9 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat @@ -0,0 +1,3 @@ +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output ..\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts\CreateCatalogDb.sql +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output ..\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts\CreateCatalogDb.sql +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output ..\Nethereum.eShop.MySql\Catalog\Migrations\Scripts\CreateCatalogDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat b/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat new file mode 100644 index 0000000..46fa552 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat @@ -0,0 +1,3 @@ +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output ..\Nethereum.eShop.SqlServer\Identity\Migrations\Scripts\CreateIdentityDb.sql +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output ..\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts\CreateIdentityDb.sql +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output ..\Nethereum.eShop.MySql\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs new file mode 100644 index 0000000..3314808 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs @@ -0,0 +1,916 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + [Migration("20200312152404_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs new file mode 100644 index 0000000..d6cab2d --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs @@ -0,0 +1,458 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Baskets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true), + TransactionHash = table.Column(maxLength: 67, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Baskets", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Buyers", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Buyers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogBrands", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Brand = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogBrands", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Type = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + QuoteId = table.Column(nullable: true), + Status = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + PoDate = table.Column(nullable: true), + OrderDate = table.Column(nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Quotes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Status = table.Column(nullable: false), + Date = table.Column(nullable: false), + Expiry = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Quotes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "BasketItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + CatalogItemId = table.Column(nullable: false), + BasketId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BasketItems", x => x.Id); + table.ForeignKey( + name: "FK_BasketItems_Baskets_BasketId", + column: x => x.BasketId, + principalTable: "Baskets", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "BuyerPostalAddress", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(nullable: true), + PostalAddress_RecipientName = table.Column(maxLength: 255, nullable: true), + PostalAddress_Street = table.Column(maxLength: 180, nullable: true), + PostalAddress_City = table.Column(maxLength: 100, nullable: true), + PostalAddress_State = table.Column(maxLength: 60, nullable: true), + PostalAddress_Country = table.Column(maxLength: 90, nullable: true), + PostalAddress_ZipCode = table.Column(maxLength: 18, nullable: true), + BuyerId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_BuyerPostalAddress", x => x.Id); + table.ForeignKey( + name: "FK_BuyerPostalAddress_Buyers_BuyerId", + column: x => x.BuyerId, + principalTable: "Buyers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Catalog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Status = table.Column(nullable: false), + Gtin = table.Column(maxLength: 14, nullable: false), + GtinRegistryId = table.Column(nullable: true), + Name = table.Column(maxLength: 50, nullable: false), + Description = table.Column(nullable: true), + Price = table.Column(type: "decimal(18,2)", nullable: false), + Unit = table.Column(maxLength: 8, nullable: true), + CatalogTypeId = table.Column(nullable: false), + CatalogBrandId = table.Column(nullable: false), + PictureUri = table.Column(maxLength: 512, nullable: true), + PictureSmallUri = table.Column(maxLength: 512, nullable: true), + PictureMediumUri = table.Column(maxLength: 512, nullable: true), + PictureLargeUri = table.Column(maxLength: 512, nullable: true), + AttributeJson = table.Column(nullable: true), + Rank = table.Column(nullable: false), + Height = table.Column(nullable: false), + Width = table.Column(nullable: false), + Depth = table.Column(nullable: false), + Weight = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Catalog", x => x.Id); + table.ForeignKey( + name: "FK_Catalog_CatalogBrands_CatalogBrandId", + column: x => x.CatalogBrandId, + principalTable: "CatalogBrands", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Catalog_CatalogTypes_CatalogTypeId", + column: x => x.CatalogTypeId, + principalTable: "CatalogTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OrderItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Status = table.Column(nullable: false), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(maxLength: 50, nullable: true), + PoItemStatus = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + GoodsIssueDate = table.Column(nullable: true), + ActualEscrowReleaseDate = table.Column(nullable: true), + PlannedEscrowReleaseDate = table.Column(nullable: true), + IsEscrowReleased = table.Column(nullable: true), + QuantitySymbol = table.Column(maxLength: 32, nullable: true), + QuantityAddress = table.Column(maxLength: 43, nullable: true), + CurrencyValue = table.Column(maxLength: 100, nullable: true), + OrderId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OrderItems", x => x.Id); + table.ForeignKey( + name: "FK_OrderItems_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "QuoteItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + EscrowReleaseDate = table.Column(nullable: true), + QuantitySymbol = table.Column(nullable: true), + QuantityAddress = table.Column(nullable: true), + CurrencyValue = table.Column(nullable: true), + QuoteId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QuoteItems", x => x.Id); + table.ForeignKey( + name: "FK_QuoteItems_Quotes_QuoteId", + column: x => x.QuoteId, + principalTable: "Quotes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Stock", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CatalogItemId = table.Column(nullable: false), + Location = table.Column(maxLength: 50, nullable: false), + Quantity = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Stock", x => x.Id); + table.ForeignKey( + name: "FK_Stock_Catalog_CatalogItemId", + column: x => x.CatalogItemId, + principalTable: "Catalog", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_BasketItems_BasketId", + table: "BasketItems", + column: "BasketId"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerAddress", + table: "Baskets", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerId", + table: "Baskets", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_BuyerPostalAddress_BuyerId", + table: "BuyerPostalAddress", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerAddress", + table: "Buyers", + column: "BuyerAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerId", + table: "Buyers", + column: "BuyerId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers", + column: "BuyerWalletAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogBrandId", + table: "Catalog", + column: "CatalogBrandId"); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogTypeId", + table: "Catalog", + column: "CatalogTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_OrderItems_OrderId", + table: "OrderItems", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerId", + table: "Orders", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_QuoteItems_QuoteId", + table: "QuoteItems", + column: "QuoteId"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerAddress", + table: "Quotes", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerId", + table: "Quotes", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Stock_CatalogItemId", + table: "Stock", + column: "CatalogItemId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BasketItems"); + + migrationBuilder.DropTable( + name: "BuyerPostalAddress"); + + migrationBuilder.DropTable( + name: "OrderItems"); + + migrationBuilder.DropTable( + name: "QuoteItems"); + + migrationBuilder.DropTable( + name: "Stock"); + + migrationBuilder.DropTable( + name: "Baskets"); + + migrationBuilder.DropTable( + name: "Buyers"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Quotes"); + + migrationBuilder.DropTable( + name: "Catalog"); + + migrationBuilder.DropTable( + name: "CatalogBrands"); + + migrationBuilder.DropTable( + name: "CatalogTypes"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs new file mode 100644 index 0000000..68fb5f1 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs @@ -0,0 +1,906 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + [Migration("20200331114834_RemoveBuyerAndWalletAddress")] + partial class RemoveBuyerAndWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs new file mode 100644 index 0000000..ac2a56b --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + public partial class RemoveBuyerAndWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ApproverAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "BuyerAddress", + table: "Orders"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ApproverAddress", + table: "Orders", + type: "varchar(43) CHARACTER SET utf8mb4", + maxLength: 43, + nullable: true); + + migrationBuilder.AddColumn( + name: "BuyerAddress", + table: "Orders", + type: "varchar(43) CHARACTER SET utf8mb4", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs new file mode 100644 index 0000000..474c0ac --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs @@ -0,0 +1,926 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + [Migration("20200403114515_CreateSettingsTable")] + partial class CreateSettingsTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs new file mode 100644 index 0000000..d24c876 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + public partial class CreateSettingsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(maxLength: 100, nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Settings_Key", + table: "Settings", + column: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs new file mode 100644 index 0000000..8ffec0d --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs @@ -0,0 +1,924 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + partial class MySqlCatalogContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql new file mode 100644 index 0000000..ef482d3 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -0,0 +1,735 @@ +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(95) NOT NULL, + `ProductVersion` varchar(32) NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +); + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Baskets` ( + `Id` int NOT NULL AUTO_INCREMENT, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NOT NULL, + `BillTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `BillTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `BillTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `BillTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `BillTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `BillTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `ShipTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `ShipTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `ShipTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `ShipTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `ShipTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `ShipTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `TransactionHash` varchar(67) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Baskets` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Buyers` ( + `Id` int NOT NULL AUTO_INCREMENT, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `BuyerWalletAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Buyers` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `CatalogBrands` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Brand` varchar(100) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_CatalogBrands` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `CatalogTypes` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Type` varchar(100) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_CatalogTypes` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Orders` ( + `Id` int NOT NULL AUTO_INCREMENT, + `QuoteId` int NULL, + `Status` int NOT NULL, + `TransactionHash` varchar(67) CHARACTER SET utf8mb4 NULL, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencyAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencySymbol` varchar(32) CHARACTER SET utf8mb4 NULL, + `ApproverAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `PoNumber` bigint NULL, + `PoType` int NOT NULL, + `BuyerWalletAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `SellerId` varchar(32) CHARACTER SET utf8mb4 NULL, + `PoDate` datetime(6) NULL, + `OrderDate` datetime(6) NOT NULL, + `BillTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `BillTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `BillTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `BillTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `BillTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `BillTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `ShipTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `ShipTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `ShipTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `ShipTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `ShipTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `ShipTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Orders` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Quotes` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Status` int NOT NULL, + `Date` datetime(6) NOT NULL, + `Expiry` datetime(6) NOT NULL, + `TransactionHash` varchar(67) CHARACTER SET utf8mb4 NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencySymbol` varchar(32) CHARACTER SET utf8mb4 NULL, + `CurrencyAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `ApproverAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `PoNumber` bigint NULL, + `PoType` int NOT NULL, + `BuyerWalletAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `SellerId` varchar(32) CHARACTER SET utf8mb4 NULL, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BillTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `BillTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `BillTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `BillTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `BillTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `BillTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `ShipTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `ShipTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `ShipTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `ShipTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `ShipTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `ShipTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Quotes` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `BasketItems` ( + `Id` int NOT NULL AUTO_INCREMENT, + `UnitPrice` decimal(18,2) NOT NULL, + `Quantity` int NOT NULL, + `CatalogItemId` int NOT NULL, + `BasketId` int NOT NULL, + CONSTRAINT `PK_BasketItems` PRIMARY KEY (`Id`), + CONSTRAINT `FK_BasketItems_Baskets_BasketId` FOREIGN KEY (`BasketId`) REFERENCES `Baskets` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `BuyerPostalAddress` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Name` longtext CHARACTER SET utf8mb4 NULL, + `PostalAddress_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `PostalAddress_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `PostalAddress_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `PostalAddress_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `PostalAddress_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `PostalAddress_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `BuyerId` int NULL, + CONSTRAINT `PK_BuyerPostalAddress` PRIMARY KEY (`Id`), + CONSTRAINT `FK_BuyerPostalAddress_Buyers_BuyerId` FOREIGN KEY (`BuyerId`) REFERENCES `Buyers` (`Id`) ON DELETE RESTRICT + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Catalog` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Status` int NOT NULL, + `Gtin` varchar(14) CHARACTER SET utf8mb4 NOT NULL, + `GtinRegistryId` int NULL, + `Name` varchar(50) CHARACTER SET utf8mb4 NOT NULL, + `Description` longtext CHARACTER SET utf8mb4 NULL, + `Price` decimal(18,2) NOT NULL, + `Unit` varchar(8) CHARACTER SET utf8mb4 NULL, + `CatalogTypeId` int NOT NULL, + `CatalogBrandId` int NOT NULL, + `PictureUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `PictureSmallUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `PictureMediumUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `PictureLargeUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `AttributeJson` longtext CHARACTER SET utf8mb4 NULL, + `Rank` int NOT NULL, + `Height` int NOT NULL, + `Width` int NOT NULL, + `Depth` int NOT NULL, + `Weight` int NOT NULL, + CONSTRAINT `PK_Catalog` PRIMARY KEY (`Id`), + CONSTRAINT `FK_Catalog_CatalogBrands_CatalogBrandId` FOREIGN KEY (`CatalogBrandId`) REFERENCES `CatalogBrands` (`Id`) ON DELETE CASCADE, + CONSTRAINT `FK_Catalog_CatalogTypes_CatalogTypeId` FOREIGN KEY (`CatalogTypeId`) REFERENCES `CatalogTypes` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `OrderItems` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Status` int NOT NULL, + `ItemOrdered_CatalogItemId` int NULL, + `ItemOrdered_Gtin` varchar(14) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_GtinRegistryId` int NULL, + `ItemOrdered_ProductName` varchar(50) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_PictureUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `UnitPrice` decimal(18,2) NOT NULL, + `Quantity` int NOT NULL, + `Unit` varchar(50) CHARACTER SET utf8mb4 NULL, + `PoItemStatus` int NULL, + `PoItemNumber` int NULL, + `GoodsIssueDate` datetime(6) NULL, + `ActualEscrowReleaseDate` datetime(6) NULL, + `PlannedEscrowReleaseDate` datetime(6) NULL, + `IsEscrowReleased` tinyint(1) NULL, + `QuantitySymbol` varchar(32) CHARACTER SET utf8mb4 NULL, + `QuantityAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencyValue` varchar(100) CHARACTER SET utf8mb4 NULL, + `OrderId` int NULL, + CONSTRAINT `PK_OrderItems` PRIMARY KEY (`Id`), + CONSTRAINT `FK_OrderItems_Orders_OrderId` FOREIGN KEY (`OrderId`) REFERENCES `Orders` (`Id`) ON DELETE RESTRICT + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `QuoteItems` ( + `Id` int NOT NULL AUTO_INCREMENT, + `ItemOrdered_CatalogItemId` int NULL, + `ItemOrdered_Gtin` varchar(14) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_GtinRegistryId` int NULL, + `ItemOrdered_ProductName` varchar(50) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_PictureUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `UnitPrice` decimal(18,2) NOT NULL, + `Quantity` int NOT NULL, + `Unit` longtext CHARACTER SET utf8mb4 NULL, + `PoItemNumber` int NULL, + `EscrowReleaseDate` datetime(6) NULL, + `QuantitySymbol` longtext CHARACTER SET utf8mb4 NULL, + `QuantityAddress` longtext CHARACTER SET utf8mb4 NULL, + `CurrencyValue` longtext CHARACTER SET utf8mb4 NULL, + `QuoteId` int NULL, + CONSTRAINT `PK_QuoteItems` PRIMARY KEY (`Id`), + CONSTRAINT `FK_QuoteItems_Quotes_QuoteId` FOREIGN KEY (`QuoteId`) REFERENCES `Quotes` (`Id`) ON DELETE RESTRICT + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Stock` ( + `Id` int NOT NULL AUTO_INCREMENT, + `CatalogItemId` int NOT NULL, + `Location` varchar(50) CHARACTER SET utf8mb4 NOT NULL, + `Quantity` int NOT NULL, + CONSTRAINT `PK_Stock` PRIMARY KEY (`Id`), + CONSTRAINT `FK_Stock_Catalog_CatalogItemId` FOREIGN KEY (`CatalogItemId`) REFERENCES `Catalog` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_BasketItems_BasketId` ON `BasketItems` (`BasketId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Baskets_BuyerAddress` ON `Baskets` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Baskets_BuyerId` ON `Baskets` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_BuyerPostalAddress_BuyerId` ON `BuyerPostalAddress` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE UNIQUE INDEX `IX_Buyers_BuyerAddress` ON `Buyers` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE UNIQUE INDEX `IX_Buyers_BuyerId` ON `Buyers` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE UNIQUE INDEX `IX_Buyers_BuyerWalletAddress` ON `Buyers` (`BuyerWalletAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Catalog_CatalogBrandId` ON `Catalog` (`CatalogBrandId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Catalog_CatalogTypeId` ON `Catalog` (`CatalogTypeId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_OrderItems_OrderId` ON `OrderItems` (`OrderId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Orders_BuyerAddress` ON `Orders` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Orders_BuyerId` ON `Orders` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_QuoteItems_QuoteId` ON `QuoteItems` (`QuoteId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Quotes_BuyerAddress` ON `Quotes` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Quotes_BuyerId` ON `Quotes` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Stock_CatalogItemId` ON `Stock` (`CatalogItemId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200312152404_InitialCreate', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + ALTER TABLE `Orders` DROP INDEX `IX_Orders_BuyerAddress`; + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + ALTER TABLE `Orders` DROP COLUMN `ApproverAddress`; + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + ALTER TABLE `Orders` DROP COLUMN `BuyerAddress`; + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200331114834_RemoveBuyerAndWalletAddress', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200403114515_CreateSettingsTable') THEN + + CREATE TABLE `Settings` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Key` varchar(100) CHARACTER SET utf8mb4 NULL, + `Value` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Settings` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200403114515_CreateSettingsTable') THEN + + CREATE INDEX `IX_Settings_Key` ON `Settings` (`Key`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200403114515_CreateSettingsTable') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200403114515_CreateSettingsTable', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + diff --git a/src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs b/src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs new file mode 100644 index 0000000..040a82a --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs @@ -0,0 +1,31 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.MySql.Catalog +{ + public class MySqlCatalogContext : CatalogContext + { + public MySqlCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + //config is in EntityFramework project + builder.ApplyConfigurationsFromAssembly(typeof(CatalogContext).Assembly); + } + } + + public class MySqlCatalogContextContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public MySqlCatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql("server=localhost;database=library;user=user;password=password"); + return new MySqlCatalogContext(optionsBuilder.Options, null); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs b/src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs new file mode 100644 index 0000000..c83cac2 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.MySql.Catalog.Queries; + +namespace Nethereum.eShop.MySql.Catalog +{ + public class MySqlEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + private const string ConnectionName = "CatalogConnection_MySql"; + + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext((serviceProvider, options) => + options.UseMySql(configuration.GetConnectionString(ConnectionName))); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + string queryConnectionString = configuration.GetConnectionString(ConnectionName); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); + } + } + +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs new file mode 100644 index 0000000..767c8cc --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs @@ -0,0 +1,65 @@ +using Dapper; +using MySql.Data.MySqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.MySql.Catalog.Queries +{ + public class CatalogQueries : ICatalogQueries + { + private readonly string _connectionString; + + public CatalogQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Rank" }; + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + string sortOrder = catalogQuerySpecification.SortDescending ? "desc" : "asc"; + catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; + + if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); + + using (var connection = new MySqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@searchText", catalogQuerySpecification.SearchText); + parameters.Add("@brandId", catalogQuerySpecification.BrandId); + parameters.Add("@typeId", catalogQuerySpecification.TypeId); + + var dbResults = await connection.QueryMultipleAsync( +@$"SELECT Count(1) FROM Catalog c +INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id +INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id +WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.Name LIKE CONCAT('%', @searchText,'%'))) OR (b.Brand LIKE CONCAT('%', @searchText, '%'))); +SELECT c.Id, c.Name, c.CatalogBrandId, b.Brand, c.CatalogTypeId, t.Type, c.PictureUri, c.Price, c.Rank +FROM Catalog c +INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id +INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id +WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.Name LIKE CONCAT('%', @searchText,'%'))) OR (b.Brand LIKE CONCAT('%', @searchText, '%'))) +ORDER BY c.{catalogQuerySpecification.SortBy} {sortOrder} +LIMIT {catalogQuerySpecification.Offset},{catalogQuerySpecification.Fetch};" + , parameters + ); + + var totalCount = dbResults.Read().Single(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, catalogQuerySpecification); + } + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs new file mode 100644 index 0000000..21d8d73 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs @@ -0,0 +1,72 @@ +using Dapper; +using MySql.Data.MySqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.MySql.Catalog.Queries +{ + public class OrderQueries: IOrderQueries + { + private readonly string _connectionString; + + public OrderQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new MySqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM Orders as o WHERE o.BuyerId = @buyerId; +SELECT + o.Id as OrderId, + o.QuoteId as QuoteId, + o.BuyerId, + o.TransactionHash, + o.OrderDate, + o.Status, + o.PoNumber, + o.PoType, + o.CurrencySymbol, + o.BillTo_RecipientName, + o.BillTo_ZipCode, + o.ShipTo_RecipientName, + o.ShipTo_ZipCode, + (select sum(oi.Quantity * oi.UnitPrice) from OrderItems oi where oi.OrderId = o.Id) as Total, + (select count(1) from OrderItems oi where oi.OrderId = o.Id) as ItemCount +FROM Orders as o +WHERE o.BuyerId = @buyerId +ORDER BY o.{paginationArgs.SortBy} {sortOrder} +LIMIT {paginationArgs.Offset},{paginationArgs.Fetch}; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs new file mode 100644 index 0000000..1001a2e --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs @@ -0,0 +1,73 @@ +using Dapper; +using MySql.Data.MySqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.MySql.Catalog.Queries +{ + public class QuoteQueries: IQuoteQueries + { + private readonly string _connectionString; + + public QuoteQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new MySqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; +SELECT + q.Id as QuoteId, + q.BuyerAddress, + q.BuyerId, + q.TransactionHash, + q.Date as QuoteDate, + q.Status, + q.PoNumber, + q.PoType, + q.CurrencySymbol, + q.Expiry, + q.BillTo_RecipientName, + q.BillTo_ZipCode, + q.ShipTo_RecipientName, + q.ShipTo_ZipCode, + (select sum(qi.Quantity * qi.UnitPrice) from QuoteItems qi where qi.QuoteId = q.Id) as Total, + (select count(1) from QuoteItems qi where qi.QuoteId = q.Id) as ItemCount +FROM Quotes as q +WHERE q.BuyerId = @buyerId +ORDER BY q.{paginationArgs.SortBy} {sortOrder} +LIMIT {paginationArgs.Offset},{paginationArgs.Fetch}; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs new file mode 100644 index 0000000..1f31e3f --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs @@ -0,0 +1,267 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Identity; + +namespace Nethereum.eShop.MySql.Identity.Migrations +{ + [DbContext(typeof(MySqlAppIdentityDbContext))] + [Migration("20200312152429_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Email") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumber") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs new file mode 100644 index 0000000..732ac1c --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs @@ -0,0 +1,218 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Identity.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs new file mode 100644 index 0000000..992bc24 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs @@ -0,0 +1,265 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Identity; + +namespace Nethereum.eShop.MySql.Identity.Migrations +{ + [DbContext(typeof(MySqlAppIdentityDbContext))] + partial class MySqlAppIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Email") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumber") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql new file mode 100644 index 0000000..5a408b3 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -0,0 +1,289 @@ +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(95) NOT NULL, + `ProductVersion` varchar(32) NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +); + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetRoles` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Name` varchar(256) CHARACTER SET utf8mb4 NULL, + `NormalizedName` varchar(256) CHARACTER SET utf8mb4 NULL, + `ConcurrencyStamp` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetRoles` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUsers` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `UserName` varchar(256) CHARACTER SET utf8mb4 NULL, + `NormalizedUserName` varchar(256) CHARACTER SET utf8mb4 NULL, + `Email` varchar(256) CHARACTER SET utf8mb4 NULL, + `NormalizedEmail` varchar(256) CHARACTER SET utf8mb4 NULL, + `EmailConfirmed` tinyint(1) NOT NULL, + `PasswordHash` longtext CHARACTER SET utf8mb4 NULL, + `SecurityStamp` longtext CHARACTER SET utf8mb4 NULL, + `ConcurrencyStamp` longtext CHARACTER SET utf8mb4 NULL, + `PhoneNumber` longtext CHARACTER SET utf8mb4 NULL, + `PhoneNumberConfirmed` tinyint(1) NOT NULL, + `TwoFactorEnabled` tinyint(1) NOT NULL, + `LockoutEnd` datetime(6) NULL, + `LockoutEnabled` tinyint(1) NOT NULL, + `AccessFailedCount` int NOT NULL, + CONSTRAINT `PK_AspNetUsers` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetRoleClaims` ( + `Id` int NOT NULL AUTO_INCREMENT, + `RoleId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ClaimType` longtext CHARACTER SET utf8mb4 NULL, + `ClaimValue` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetRoleClaims` PRIMARY KEY (`Id`), + CONSTRAINT `FK_AspNetRoleClaims_AspNetRoles_RoleId` FOREIGN KEY (`RoleId`) REFERENCES `AspNetRoles` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserClaims` ( + `Id` int NOT NULL AUTO_INCREMENT, + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ClaimType` longtext CHARACTER SET utf8mb4 NULL, + `ClaimValue` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetUserClaims` PRIMARY KEY (`Id`), + CONSTRAINT `FK_AspNetUserClaims_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserLogins` ( + `LoginProvider` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ProviderKey` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ProviderDisplayName` longtext CHARACTER SET utf8mb4 NULL, + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_AspNetUserLogins` PRIMARY KEY (`LoginProvider`, `ProviderKey`), + CONSTRAINT `FK_AspNetUserLogins_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserRoles` ( + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `RoleId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_AspNetUserRoles` PRIMARY KEY (`UserId`, `RoleId`), + CONSTRAINT `FK_AspNetUserRoles_AspNetRoles_RoleId` FOREIGN KEY (`RoleId`) REFERENCES `AspNetRoles` (`Id`) ON DELETE CASCADE, + CONSTRAINT `FK_AspNetUserRoles_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserTokens` ( + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `LoginProvider` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Name` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Value` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetUserTokens` PRIMARY KEY (`UserId`, `LoginProvider`, `Name`), + CONSTRAINT `FK_AspNetUserTokens_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetRoleClaims_RoleId` ON `AspNetRoleClaims` (`RoleId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE UNIQUE INDEX `RoleNameIndex` ON `AspNetRoles` (`NormalizedName`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetUserClaims_UserId` ON `AspNetUserClaims` (`UserId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetUserLogins_UserId` ON `AspNetUserLogins` (`UserId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetUserRoles_RoleId` ON `AspNetUserRoles` (`RoleId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `EmailIndex` ON `AspNetUsers` (`NormalizedEmail`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE UNIQUE INDEX `UserNameIndex` ON `AspNetUsers` (`NormalizedUserName`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200312152429_InitialCreate', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + diff --git a/src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs b/src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs new file mode 100644 index 0000000..b58ebd2 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.MySql.Identity +{ + public class MySqlAppIdentityDbContext : AppIdentityDbContext + { + public MySqlAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } + + public class MySqlAppIdentityDbContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public MySqlAppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql("server=localhost;database=library;user=user;password=password"); + + return new MySqlAppIdentityDbContext( + optionsBuilder.Options); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..671f915 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.MySql.Identity +{ + public class MySqlEShopAppIdentityDbBootstrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseMySql(configuration.GetConnectionString("IdentityConnection_MySql"))); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj b/src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj new file mode 100644 index 0000000..d41681d --- /dev/null +++ b/src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.1 + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketConfiguration.cs new file mode 100644 index 0000000..8aad972 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class BasketConfiguration : b.BasketConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketItemConfiguration.cs new file mode 100644 index 0000000..3527e9f --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketItemConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class BasketItemConfiguration : b.BasketItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerConfiguration.cs new file mode 100644 index 0000000..e8a7ea3 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class BuyerConfiguration : b.BuyerConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs new file mode 100644 index 0000000..e870ee5 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class BuyerPostalAddressConfiguration : b.BuyerPostalAddressConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogBrandConfiguration.cs new file mode 100644 index 0000000..c9b80a6 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogBrandConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class CatalogBrandConfiguration : b.CatalogBrandConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + builder.Property(ci => ci.Id) + .UseHiLo("catalog_brand_hilo"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogItemConfiguration.cs new file mode 100644 index 0000000..b815133 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogItemConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class CatalogItemConfiguration : b.CatalogItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + builder.Property(ci => ci.Id) + .UseHiLo("catalog_hilo"); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogTypeConfiguration.cs similarity index 82% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogTypeConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogTypeConfiguration.cs index 02e9ef8..957617d 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogTypeConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogTypeConfiguration.cs @@ -1,8 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class CatalogTypeConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderConfiguration.cs new file mode 100644 index 0000000..3232248 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class OrderConfiguration : b.OrderConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderItemConfiguration.cs new file mode 100644 index 0000000..f89f2bf --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderItemConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class OrderItemConfiguration : b.OrderItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteConfiguration.cs new file mode 100644 index 0000000..4c8a7fe --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class QuoteConfiguration : b.QuoteConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteItemConfiguration.cs new file mode 100644 index 0000000..10e8429 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteItemConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class QuoteItemConfiguration : b.QuoteItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/StockItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/StockItemConfiguration.cs new file mode 100644 index 0000000..2ceea67 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/StockItemConfiguration.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; + +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders +{ + public class StockItemConfiguration : b.StockItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + + builder.Property(ci => ci.Id) + .UseHiLo("stock_hilo"); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.Designer.cs similarity index 94% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.Designer.cs index f556017..905f24a 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.Designer.cs @@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.SqlServer.Catalog; -namespace Nethereum.eShop.Infrastructure.Data.Migrations +namespace Nethereum.eShop.SqlServer.Catalog.Migrations { - [DbContext(typeof(CatalogContext))] - [Migration("20200221124040_InitialCreate")] + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200311151648_InitialCreate")] partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") @@ -43,7 +43,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasMaxLength(256); b.Property("TransactionHash") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); b.HasKey("Id"); @@ -186,16 +187,20 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasMaxLength(50); b.Property("PictureLargeUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureMediumUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureSmallUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("Price") .HasColumnType("decimal(18,2)"); @@ -268,10 +273,12 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasMaxLength(43); b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("OrderDate") .HasColumnType("datetimeoffset"); @@ -289,7 +296,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("SellerId") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); @@ -318,7 +326,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("datetimeoffset"); b.Property("CurrencyValue") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); b.Property("GoodsIssueDate") .HasColumnType("datetimeoffset"); @@ -342,16 +351,19 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("QuantityAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("QuantitySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); b.Property("Unit") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); b.Property("UnitPrice") .HasColumnType("decimal(18,2)"); @@ -388,10 +400,12 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasMaxLength(43); b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Date") .HasColumnType("datetimeoffset"); @@ -406,7 +420,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("SellerId") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); @@ -765,13 +780,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("int"); b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); b1.Property("GtinRegistryId") .HasColumnType("int"); b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b1.Property("ProductName") .IsRequired() @@ -895,13 +912,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("int"); b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); b1.Property("GtinRegistryId") .HasColumnType("int"); b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b1.Property("ProductName") .IsRequired() diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.cs similarity index 92% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.cs index 5dba2d3..3be81b1 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace Nethereum.eShop.Infrastructure.Data.Migrations +namespace Nethereum.eShop.SqlServer.Catalog.Migrations { public partial class InitialCreate : Migration { @@ -43,7 +43,7 @@ protected override void Up(MigrationBuilder migrationBuilder) ShipTo_State = table.Column(maxLength: 60, nullable: true), ShipTo_Country = table.Column(maxLength: 90, nullable: true), ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true), - TransactionHash = table.Column(nullable: true) + TransactionHash = table.Column(maxLength: 67, nullable: true) }, constraints: table => { @@ -99,13 +99,13 @@ protected override void Up(MigrationBuilder migrationBuilder) TransactionHash = table.Column(maxLength: 67, nullable: true), BuyerId = table.Column(maxLength: 256, nullable: false), BuyerAddress = table.Column(maxLength: 43, nullable: true), - CurrencyAddress = table.Column(nullable: true), - CurrencySymbol = table.Column(nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), ApproverAddress = table.Column(maxLength: 43, nullable: true), PoNumber = table.Column(nullable: true), PoType = table.Column(nullable: false), BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), - SellerId = table.Column(nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), PoDate = table.Column(nullable: true), OrderDate = table.Column(nullable: false), BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), @@ -137,13 +137,13 @@ protected override void Up(MigrationBuilder migrationBuilder) Expiry = table.Column(nullable: false), TransactionHash = table.Column(maxLength: 67, nullable: true), BuyerAddress = table.Column(maxLength: 43, nullable: true), - CurrencySymbol = table.Column(nullable: true), - CurrencyAddress = table.Column(nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), ApproverAddress = table.Column(maxLength: 43, nullable: true), PoNumber = table.Column(nullable: true), PoType = table.Column(nullable: false), BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), - SellerId = table.Column(nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), BuyerId = table.Column(maxLength: 256, nullable: false), BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), BillTo_Street = table.Column(maxLength: 180, nullable: true), @@ -225,10 +225,10 @@ protected override void Up(MigrationBuilder migrationBuilder) Unit = table.Column(maxLength: 8, nullable: true), CatalogTypeId = table.Column(nullable: false), CatalogBrandId = table.Column(nullable: false), - PictureUri = table.Column(nullable: true), - PictureSmallUri = table.Column(nullable: true), - PictureMediumUri = table.Column(nullable: true), - PictureLargeUri = table.Column(nullable: true), + PictureUri = table.Column(maxLength: 512, nullable: true), + PictureSmallUri = table.Column(maxLength: 512, nullable: true), + PictureMediumUri = table.Column(maxLength: 512, nullable: true), + PictureLargeUri = table.Column(maxLength: 512, nullable: true), AttributeJson = table.Column(nullable: true), Rank = table.Column(nullable: false), Height = table.Column(nullable: false), @@ -261,22 +261,22 @@ protected override void Up(MigrationBuilder migrationBuilder) .Annotation("SqlServer:Identity", "1, 1"), Status = table.Column(nullable: false), ItemOrdered_CatalogItemId = table.Column(nullable: true), - ItemOrdered_Gtin = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), ItemOrdered_GtinRegistryId = table.Column(nullable: true), ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), - ItemOrdered_PictureUri = table.Column(nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), Quantity = table.Column(nullable: false), - Unit = table.Column(nullable: true), + Unit = table.Column(maxLength: 50, nullable: true), PoItemStatus = table.Column(nullable: true), PoItemNumber = table.Column(nullable: true), GoodsIssueDate = table.Column(nullable: true), ActualEscrowReleaseDate = table.Column(nullable: true), PlannedEscrowReleaseDate = table.Column(nullable: true), IsEscrowReleased = table.Column(nullable: true), - QuantitySymbol = table.Column(nullable: true), - QuantityAddress = table.Column(nullable: true), - CurrencyValue = table.Column(nullable: true), + QuantitySymbol = table.Column(maxLength: 32, nullable: true), + QuantityAddress = table.Column(maxLength: 43, nullable: true), + CurrencyValue = table.Column(maxLength: 100, nullable: true), OrderId = table.Column(nullable: true) }, constraints: table => @@ -297,10 +297,10 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(nullable: false) .Annotation("SqlServer:Identity", "1, 1"), ItemOrdered_CatalogItemId = table.Column(nullable: true), - ItemOrdered_Gtin = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), ItemOrdered_GtinRegistryId = table.Column(nullable: true), ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), - ItemOrdered_PictureUri = table.Column(nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), Quantity = table.Column(nullable: false), Unit = table.Column(nullable: true), diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..0955c80 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs @@ -0,0 +1,958 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200311172359_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs new file mode 100644 index 0000000..d211cca --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BuyerWalletAddress", + table: "Buyers", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers", + column: "BuyerWalletAddress", + unique: true, + filter: "[BuyerWalletAddress] IS NOT NULL"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers"); + + migrationBuilder.DropColumn( + name: "BuyerWalletAddress", + table: "Buyers"); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs similarity index 93% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs index b5cb66d..b48c11d 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs @@ -3,19 +3,21 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.SqlServer.Catalog; -namespace Nethereum.eShop.Infrastructure.Data.Migrations +namespace Nethereum.eShop.SqlServer.Catalog.Migrations { - [DbContext(typeof(CatalogContext))] - partial class CatalogContextModelSnapshot : ModelSnapshot + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200331114818_RemoveBuyerAndWalletAddress")] + partial class RemoveBuyerAndWalletAddress { - protected override void BuildModel(ModelBuilder modelBuilder) + protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") @@ -41,7 +43,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(256); b.Property("TransactionHash") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); b.HasKey("Id"); @@ -94,6 +97,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(256)") .HasMaxLength(256); + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + b.HasKey("Id"); b.HasIndex("BuyerAddress") @@ -103,6 +110,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("BuyerId") .IsUnique(); + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + b.ToTable("Buyers"); }); @@ -184,16 +195,20 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(50); b.Property("PictureLargeUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureMediumUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureSmallUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("Price") .HasColumnType("decimal(18,2)"); @@ -248,14 +263,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - b.Property("ApproverAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - b.Property("BuyerId") .IsRequired() .HasColumnType("nvarchar(256)") @@ -266,10 +273,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(43); b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("OrderDate") .HasColumnType("datetimeoffset"); @@ -287,7 +296,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("SellerId") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); @@ -298,8 +308,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("BuyerAddress"); - b.HasIndex("BuyerId"); b.ToTable("Orders"); @@ -316,7 +324,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("datetimeoffset"); b.Property("CurrencyValue") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); b.Property("GoodsIssueDate") .HasColumnType("datetimeoffset"); @@ -340,16 +349,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("QuantityAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("QuantitySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); b.Property("Unit") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); b.Property("UnitPrice") .HasColumnType("decimal(18,2)"); @@ -386,10 +398,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(43); b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Date") .HasColumnType("datetimeoffset"); @@ -404,7 +418,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("SellerId") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); @@ -763,13 +778,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); b1.Property("GtinRegistryId") .HasColumnType("int"); b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b1.Property("ProductName") .IsRequired() @@ -893,13 +910,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); b1.Property("GtinRegistryId") .HasColumnType("int"); b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b1.Property("ProductName") .IsRequired() diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs new file mode 100644 index 0000000..ec806a0 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + public partial class RemoveBuyerAndWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ApproverAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "BuyerAddress", + table: "Orders"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ApproverAddress", + table: "Orders", + type: "nvarchar(43)", + maxLength: 43, + nullable: true); + + migrationBuilder.AddColumn( + name: "BuyerAddress", + table: "Orders", + type: "nvarchar(43)", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs new file mode 100644 index 0000000..3c74af2 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs @@ -0,0 +1,966 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200403114458_CreateSettingsTable")] + partial class CreateSettingsTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs new file mode 100644 index 0000000..7fd6e30 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + public partial class CreateSettingsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Key = table.Column(nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql new file mode 100644 index 0000000..08432b7 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -0,0 +1,499 @@ +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [catalog_brand_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [catalog_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [catalog_type_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [stock_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Baskets] ( + [Id] int NOT NULL IDENTITY, + [BuyerId] nvarchar(256) NOT NULL, + [BuyerAddress] nvarchar(43) NOT NULL, + [BillTo_RecipientName] nvarchar(255) NULL, + [BillTo_Street] nvarchar(180) NULL, + [BillTo_City] nvarchar(100) NULL, + [BillTo_State] nvarchar(60) NULL, + [BillTo_Country] nvarchar(90) NULL, + [BillTo_ZipCode] nvarchar(18) NULL, + [ShipTo_RecipientName] nvarchar(255) NULL, + [ShipTo_Street] nvarchar(180) NULL, + [ShipTo_City] nvarchar(100) NULL, + [ShipTo_State] nvarchar(60) NULL, + [ShipTo_Country] nvarchar(90) NULL, + [ShipTo_ZipCode] nvarchar(18) NULL, + [TransactionHash] nvarchar(67) NULL, + CONSTRAINT [PK_Baskets] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Buyers] ( + [Id] int NOT NULL IDENTITY, + [BuyerId] nvarchar(256) NOT NULL, + [BuyerAddress] nvarchar(43) NULL, + CONSTRAINT [PK_Buyers] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [CatalogBrands] ( + [Id] int NOT NULL, + [Brand] nvarchar(100) NOT NULL, + CONSTRAINT [PK_CatalogBrands] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [CatalogTypes] ( + [Id] int NOT NULL, + [Type] nvarchar(100) NOT NULL, + CONSTRAINT [PK_CatalogTypes] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Orders] ( + [Id] int NOT NULL IDENTITY, + [QuoteId] int NULL, + [Status] int NOT NULL, + [TransactionHash] nvarchar(67) NULL, + [BuyerId] nvarchar(256) NOT NULL, + [BuyerAddress] nvarchar(43) NULL, + [CurrencyAddress] nvarchar(43) NULL, + [CurrencySymbol] nvarchar(32) NULL, + [ApproverAddress] nvarchar(43) NULL, + [PoNumber] bigint NULL, + [PoType] int NOT NULL, + [BuyerWalletAddress] nvarchar(43) NULL, + [SellerId] nvarchar(32) NULL, + [PoDate] datetimeoffset NULL, + [OrderDate] datetimeoffset NOT NULL, + [BillTo_RecipientName] nvarchar(255) NULL, + [BillTo_Street] nvarchar(180) NULL, + [BillTo_City] nvarchar(100) NULL, + [BillTo_State] nvarchar(60) NULL, + [BillTo_Country] nvarchar(90) NULL, + [BillTo_ZipCode] nvarchar(18) NULL, + [ShipTo_RecipientName] nvarchar(255) NULL, + [ShipTo_Street] nvarchar(180) NULL, + [ShipTo_City] nvarchar(100) NULL, + [ShipTo_State] nvarchar(60) NULL, + [ShipTo_Country] nvarchar(90) NULL, + [ShipTo_ZipCode] nvarchar(18) NULL, + CONSTRAINT [PK_Orders] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Quotes] ( + [Id] int NOT NULL IDENTITY, + [Status] int NOT NULL, + [Date] datetimeoffset NOT NULL, + [Expiry] datetimeoffset NOT NULL, + [TransactionHash] nvarchar(67) NULL, + [BuyerAddress] nvarchar(43) NULL, + [CurrencySymbol] nvarchar(32) NULL, + [CurrencyAddress] nvarchar(43) NULL, + [ApproverAddress] nvarchar(43) NULL, + [PoNumber] bigint NULL, + [PoType] int NOT NULL, + [BuyerWalletAddress] nvarchar(43) NULL, + [SellerId] nvarchar(32) NULL, + [BuyerId] nvarchar(256) NOT NULL, + [BillTo_RecipientName] nvarchar(255) NULL, + [BillTo_Street] nvarchar(180) NULL, + [BillTo_City] nvarchar(100) NULL, + [BillTo_State] nvarchar(60) NULL, + [BillTo_Country] nvarchar(90) NULL, + [BillTo_ZipCode] nvarchar(18) NULL, + [ShipTo_RecipientName] nvarchar(255) NULL, + [ShipTo_Street] nvarchar(180) NULL, + [ShipTo_City] nvarchar(100) NULL, + [ShipTo_State] nvarchar(60) NULL, + [ShipTo_Country] nvarchar(90) NULL, + [ShipTo_ZipCode] nvarchar(18) NULL, + CONSTRAINT [PK_Quotes] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [BasketItems] ( + [Id] int NOT NULL IDENTITY, + [UnitPrice] decimal(18,2) NOT NULL, + [Quantity] int NOT NULL, + [CatalogItemId] int NOT NULL, + [BasketId] int NOT NULL, + CONSTRAINT [PK_BasketItems] PRIMARY KEY ([Id]), + CONSTRAINT [FK_BasketItems_Baskets_BasketId] FOREIGN KEY ([BasketId]) REFERENCES [Baskets] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [BuyerPostalAddress] ( + [Id] int NOT NULL IDENTITY, + [Name] nvarchar(max) NULL, + [PostalAddress_RecipientName] nvarchar(255) NULL, + [PostalAddress_Street] nvarchar(180) NULL, + [PostalAddress_City] nvarchar(100) NULL, + [PostalAddress_State] nvarchar(60) NULL, + [PostalAddress_Country] nvarchar(90) NULL, + [PostalAddress_ZipCode] nvarchar(18) NULL, + [BuyerId] int NULL, + CONSTRAINT [PK_BuyerPostalAddress] PRIMARY KEY ([Id]), + CONSTRAINT [FK_BuyerPostalAddress_Buyers_BuyerId] FOREIGN KEY ([BuyerId]) REFERENCES [Buyers] ([Id]) ON DELETE NO ACTION + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Catalog] ( + [Id] int NOT NULL, + [Status] int NOT NULL, + [Gtin] nvarchar(14) NOT NULL, + [GtinRegistryId] int NULL, + [Name] nvarchar(50) NOT NULL, + [Description] nvarchar(max) NULL, + [Price] decimal(18,2) NOT NULL, + [Unit] nvarchar(8) NULL, + [CatalogTypeId] int NOT NULL, + [CatalogBrandId] int NOT NULL, + [PictureUri] nvarchar(512) NULL, + [PictureSmallUri] nvarchar(512) NULL, + [PictureMediumUri] nvarchar(512) NULL, + [PictureLargeUri] nvarchar(512) NULL, + [AttributeJson] nvarchar(max) NULL, + [Rank] int NOT NULL, + [Height] int NOT NULL, + [Width] int NOT NULL, + [Depth] int NOT NULL, + [Weight] int NOT NULL, + CONSTRAINT [PK_Catalog] PRIMARY KEY ([Id]), + CONSTRAINT [FK_Catalog_CatalogBrands_CatalogBrandId] FOREIGN KEY ([CatalogBrandId]) REFERENCES [CatalogBrands] ([Id]) ON DELETE CASCADE, + CONSTRAINT [FK_Catalog_CatalogTypes_CatalogTypeId] FOREIGN KEY ([CatalogTypeId]) REFERENCES [CatalogTypes] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [OrderItems] ( + [Id] int NOT NULL IDENTITY, + [Status] int NOT NULL, + [ItemOrdered_CatalogItemId] int NULL, + [ItemOrdered_Gtin] nvarchar(14) NULL, + [ItemOrdered_GtinRegistryId] int NULL, + [ItemOrdered_ProductName] nvarchar(50) NULL, + [ItemOrdered_PictureUri] nvarchar(512) NULL, + [UnitPrice] decimal(18,2) NOT NULL, + [Quantity] int NOT NULL, + [Unit] nvarchar(50) NULL, + [PoItemStatus] int NULL, + [PoItemNumber] int NULL, + [GoodsIssueDate] datetimeoffset NULL, + [ActualEscrowReleaseDate] datetimeoffset NULL, + [PlannedEscrowReleaseDate] datetimeoffset NULL, + [IsEscrowReleased] bit NULL, + [QuantitySymbol] nvarchar(32) NULL, + [QuantityAddress] nvarchar(43) NULL, + [CurrencyValue] nvarchar(100) NULL, + [OrderId] int NULL, + CONSTRAINT [PK_OrderItems] PRIMARY KEY ([Id]), + CONSTRAINT [FK_OrderItems_Orders_OrderId] FOREIGN KEY ([OrderId]) REFERENCES [Orders] ([Id]) ON DELETE NO ACTION + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [QuoteItems] ( + [Id] int NOT NULL IDENTITY, + [ItemOrdered_CatalogItemId] int NULL, + [ItemOrdered_Gtin] nvarchar(14) NULL, + [ItemOrdered_GtinRegistryId] int NULL, + [ItemOrdered_ProductName] nvarchar(50) NULL, + [ItemOrdered_PictureUri] nvarchar(512) NULL, + [UnitPrice] decimal(18,2) NOT NULL, + [Quantity] int NOT NULL, + [Unit] nvarchar(max) NULL, + [PoItemNumber] int NULL, + [EscrowReleaseDate] datetimeoffset NULL, + [QuantitySymbol] nvarchar(max) NULL, + [QuantityAddress] nvarchar(max) NULL, + [CurrencyValue] nvarchar(max) NULL, + [QuoteId] int NULL, + CONSTRAINT [PK_QuoteItems] PRIMARY KEY ([Id]), + CONSTRAINT [FK_QuoteItems_Quotes_QuoteId] FOREIGN KEY ([QuoteId]) REFERENCES [Quotes] ([Id]) ON DELETE NO ACTION + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Stock] ( + [Id] int NOT NULL, + [CatalogItemId] int NOT NULL, + [Location] nvarchar(50) NOT NULL, + [Quantity] int NOT NULL, + CONSTRAINT [PK_Stock] PRIMARY KEY ([Id]), + CONSTRAINT [FK_Stock_Catalog_CatalogItemId] FOREIGN KEY ([CatalogItemId]) REFERENCES [Catalog] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_BasketItems_BasketId] ON [BasketItems] ([BasketId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Baskets_BuyerAddress] ON [Baskets] ([BuyerAddress]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Baskets_BuyerId] ON [Baskets] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_BuyerPostalAddress_BuyerId] ON [BuyerPostalAddress] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [IX_Buyers_BuyerAddress] ON [Buyers] ([BuyerAddress]) WHERE [BuyerAddress] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [IX_Buyers_BuyerId] ON [Buyers] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Catalog_CatalogBrandId] ON [Catalog] ([CatalogBrandId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Catalog_CatalogTypeId] ON [Catalog] ([CatalogTypeId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_OrderItems_OrderId] ON [OrderItems] ([OrderId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Orders_BuyerAddress] ON [Orders] ([BuyerAddress]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Orders_BuyerId] ON [Orders] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_QuoteItems_QuoteId] ON [QuoteItems] ([QuoteId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Quotes_BuyerAddress] ON [Quotes] ([BuyerAddress]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Quotes_BuyerId] ON [Quotes] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Stock_CatalogItemId] ON [Stock] ([CatalogItemId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311151648_InitialCreate', N'3.1.2'); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172359_BuyerWalletAddress') +BEGIN + ALTER TABLE [Buyers] ADD [BuyerWalletAddress] nvarchar(43) NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172359_BuyerWalletAddress') +BEGIN + CREATE UNIQUE INDEX [IX_Buyers_BuyerWalletAddress] ON [Buyers] ([BuyerWalletAddress]) WHERE [BuyerWalletAddress] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172359_BuyerWalletAddress') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311172359_BuyerWalletAddress', N'3.1.2'); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + DROP INDEX [IX_Orders_BuyerAddress] ON [Orders]; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + DECLARE @var0 sysname; + SELECT @var0 = [d].[name] + FROM [sys].[default_constraints] [d] + INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] + WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Orders]') AND [c].[name] = N'ApproverAddress'); + IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Orders] DROP CONSTRAINT [' + @var0 + '];'); + ALTER TABLE [Orders] DROP COLUMN [ApproverAddress]; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + DECLARE @var1 sysname; + SELECT @var1 = [d].[name] + FROM [sys].[default_constraints] [d] + INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] + WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Orders]') AND [c].[name] = N'BuyerAddress'); + IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Orders] DROP CONSTRAINT [' + @var1 + '];'); + ALTER TABLE [Orders] DROP COLUMN [BuyerAddress]; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200331114818_RemoveBuyerAndWalletAddress', N'3.1.2'); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200403114458_CreateSettingsTable') +BEGIN + CREATE TABLE [Settings] ( + [Id] int NOT NULL IDENTITY, + [Key] nvarchar(max) NULL, + [Value] nvarchar(max) NULL, + CONSTRAINT [PK_Settings] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200403114458_CreateSettingsTable') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200403114458_CreateSettingsTable', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs new file mode 100644 index 0000000..d3b8c8f --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs @@ -0,0 +1,964 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + [DbContext(typeof(SqlServerCatalogContext))] + partial class SqlServerCatalogContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Queries/CatalogQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/CatalogQueries.cs new file mode 100644 index 0000000..1d82498 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/CatalogQueries.cs @@ -0,0 +1,70 @@ +using Dapper; +using Microsoft.Data.SqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.SqlServer.Catalog.Queries +{ + public class CatalogQueries : ICatalogQueries + { + private readonly string _connectionString; + + public CatalogQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Rank" }; + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + string sortOrder = catalogQuerySpecification.SortDescending ? "desc" : "asc"; + catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; + + if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); + + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@searchText", catalogQuerySpecification.SearchText); + parameters.Add("@brandId", catalogQuerySpecification.BrandId); + parameters.Add("@typeId", catalogQuerySpecification.TypeId); + parameters.Add("@offset", catalogQuerySpecification.Offset); + parameters.Add("@fetch", catalogQuerySpecification.Fetch); + parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + + var rows = await connection.QueryAsync( +@$" + SELECT @totalCount = Count(1) FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')); + + SELECT c.Id, c.[Name], c.CatalogBrandId, b.[Brand], c.CatalogTypeId, t.[Type], c.PictureUri, c.Price, c.[Rank] + FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')) + ORDER BY [{catalogQuerySpecification.SortBy}] {sortOrder} + OFFSET @offset ROWS + FETCH NEXT @fetch ROWS ONLY; +" + , parameters + ); + + return new PaginatedResult(parameters.Get("@totalCount"), rows, catalogQuerySpecification); + } + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs new file mode 100644 index 0000000..a9abb7e --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs @@ -0,0 +1,74 @@ +using Dapper; +using Microsoft.Data.SqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.SqlServer.Catalog.Queries +{ + public class OrderQueries: IOrderQueries + { + private readonly string _connectionString; + + public OrderQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); + parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var rows = await connection.QueryAsync( +@$" +SELECT @totalCount = COUNT(1) FROM [Orders] as o WHERE o.BuyerId = @buyerId; +SELECT + o.Id as OrderId, + o.QuoteId as QuoteId, + o.BuyerId, + o.TransactionHash, + o.OrderDate, + o.Status, + o.PoNumber, + o.PoType, + o.CurrencySymbol, + o.[BillTo_RecipientName], + o.[BillTo_ZipCode], + o.[ShipTo_RecipientName], + o.[ShipTo_ZipCode], + (select sum(oi.Quantity * oi.UnitPrice) from OrderItems oi where oi.OrderId = o.Id) as Total, + (select count(1) from OrderItems oi where oi.OrderId = o.Id) as ItemCount +FROM [Orders] as o +WHERE o.BuyerId = @buyerId +ORDER BY [{paginationArgs.SortBy}] {sortOrder} +OFFSET @offset ROWS +FETCH NEXT @fetch ROWS ONLY; +" + , parameters + ); + + return new PaginatedResult(parameters.Get("@totalCount"), rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Queries/QuoteQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/QuoteQueries.cs new file mode 100644 index 0000000..8d06f0e --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/QuoteQueries.cs @@ -0,0 +1,75 @@ +using Dapper; +using Microsoft.Data.SqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.SqlServer.Catalog.Queries +{ + public class QuoteQueries: IQuoteQueries + { + private readonly string _connectionString; + + public QuoteQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); + parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var rows = await connection.QueryAsync( +@$" +SELECT @totalCount = COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; +SELECT + q.Id as QuoteId, + q.BuyerAddress, + q.BuyerId, + q.TransactionHash, + q.Date as QuoteDate, + q.Status, + q.PoNumber, + q.PoType, + q.CurrencySymbol, + q.Expiry, + q.[BillTo_RecipientName], + q.[BillTo_ZipCode], + q.[ShipTo_RecipientName], + q.[ShipTo_ZipCode], + (select sum(qi.Quantity * qi.UnitPrice) from QuoteItems qi where qi.QuoteId = q.Id) as Total, + (select count(1) from QuoteItems qi where qi.QuoteId = q.Id) as ItemCount +FROM Quotes as q +WHERE q.BuyerId = @buyerId +ORDER BY [{paginationArgs.SortBy}] {sortOrder} +OFFSET @offset ROWS +FETCH NEXT @fetch ROWS ONLY; +" + , parameters + ); + + return new PaginatedResult(parameters.Get("@totalCount"), rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs new file mode 100644 index 0000000..3bb7c72 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs @@ -0,0 +1,34 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog +{ + public class SqlServerCatalogContext : CatalogContext + { + public SqlServerCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + builder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); + } + } + + public class SqlServerCatalogContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqlServerCatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer( + "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;"); + + return new SqlServerCatalogContext( + optionsBuilder.Options, + null); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/SqlServerEShopDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerEShopDbBootstrapper.cs new file mode 100644 index 0000000..7e6f1f0 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerEShopDbBootstrapper.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.SqlServer.Catalog.Queries; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.SqlServer.Catalog +{ + public class SqlServerEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + private const string ConnectionName = "CatalogConnection_SqlServer"; + + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext((serviceProvider, options) => + options.UseSqlServer(configuration.GetConnectionString(ConnectionName))); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + string queryConnectionString = configuration.GetConnectionString(ConnectionName); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.Designer.cs similarity index 97% rename from src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.Designer.cs index b406a95..7a2c2e2 100644 --- a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.Designer.cs @@ -5,19 +5,19 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Identity; +using Nethereum.eShop.SqlServer.Identity; -namespace Nethereum.eShop.Infrastructure.Identity.Migrations +namespace Nethereum.eShop.SqlServer.Identity.Migrations { - [DbContext(typeof(AppIdentityDbContext))] - [Migration("20200221124042_InitialCreate")] + [DbContext(typeof(SqlServerAppIdentityDbContext))] + [Migration("20200311151656_InitialCreate")] partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); diff --git a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.cs similarity index 99% rename from src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.cs index 9169e04..642ab94 100644 --- a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace Nethereum.eShop.Infrastructure.Identity.Migrations +namespace Nethereum.eShop.SqlServer.Identity.Migrations { public partial class InitialCreate : Migration { diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..f011da8 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs @@ -0,0 +1,273 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Identity; + +namespace Nethereum.eShop.SqlServer.Identity.Migrations +{ + [DbContext(typeof(SqlServerAppIdentityDbContext))] + [Migration("20200311172406_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs new file mode 100644 index 0000000..0e65a84 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Identity.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql new file mode 100644 index 0000000..65efef8 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -0,0 +1,182 @@ +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetRoles] ( + [Id] nvarchar(450) NOT NULL, + [Name] nvarchar(256) NULL, + [NormalizedName] nvarchar(256) NULL, + [ConcurrencyStamp] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUsers] ( + [Id] nvarchar(450) NOT NULL, + [UserName] nvarchar(256) NULL, + [NormalizedUserName] nvarchar(256) NULL, + [Email] nvarchar(256) NULL, + [NormalizedEmail] nvarchar(256) NULL, + [EmailConfirmed] bit NOT NULL, + [PasswordHash] nvarchar(max) NULL, + [SecurityStamp] nvarchar(max) NULL, + [ConcurrencyStamp] nvarchar(max) NULL, + [PhoneNumber] nvarchar(max) NULL, + [PhoneNumberConfirmed] bit NOT NULL, + [TwoFactorEnabled] bit NOT NULL, + [LockoutEnd] datetimeoffset NULL, + [LockoutEnabled] bit NOT NULL, + [AccessFailedCount] int NOT NULL, + CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetRoleClaims] ( + [Id] int NOT NULL IDENTITY, + [RoleId] nvarchar(450) NOT NULL, + [ClaimType] nvarchar(max) NULL, + [ClaimValue] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]), + CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserClaims] ( + [Id] int NOT NULL IDENTITY, + [UserId] nvarchar(450) NOT NULL, + [ClaimType] nvarchar(max) NULL, + [ClaimValue] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]), + CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserLogins] ( + [LoginProvider] nvarchar(450) NOT NULL, + [ProviderKey] nvarchar(450) NOT NULL, + [ProviderDisplayName] nvarchar(max) NULL, + [UserId] nvarchar(450) NOT NULL, + CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]), + CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserRoles] ( + [UserId] nvarchar(450) NOT NULL, + [RoleId] nvarchar(450) NOT NULL, + CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]), + CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE, + CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserTokens] ( + [UserId] nvarchar(450) NOT NULL, + [LoginProvider] nvarchar(450) NOT NULL, + [Name] nvarchar(450) NOT NULL, + [Value] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]), + CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [AspNetRoleClaims] ([RoleId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]) WHERE [NormalizedName] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetUserClaims_UserId] ON [AspNetUserClaims] ([UserId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetUserLogins_UserId] ON [AspNetUserLogins] ([UserId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetUserRoles_RoleId] ON [AspNetUserRoles] ([RoleId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [EmailIndex] ON [AspNetUsers] ([NormalizedEmail]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]) WHERE [NormalizedUserName] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311151656_InitialCreate', N'3.1.2'); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172406_BuyerWalletAddress') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311172406_BuyerWalletAddress', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs similarity index 97% rename from src/Nethereum.eShop/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs rename to src/Nethereum.eShop.SqlServer/Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs index f778f3e..3105be0 100644 --- a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs @@ -4,18 +4,18 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Identity; +using Nethereum.eShop.SqlServer.Identity; -namespace Nethereum.eShop.Infrastructure.Identity.Migrations +namespace Nethereum.eShop.SqlServer.Identity.Migrations { - [DbContext(typeof(AppIdentityDbContext))] - partial class AppIdentityDbContextModelSnapshot : ModelSnapshot + [DbContext(typeof(SqlServerAppIdentityDbContext))] + partial class SqlServerAppIdentityDbContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); diff --git a/src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs b/src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs new file mode 100644 index 0000000..d90af41 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.SqlServer.Identity +{ + public class SqlServerAppIdentityDbContext : AppIdentityDbContext + { + public SqlServerAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } + + public class SqlServerAppIdentityContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqlServerAppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer( + "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;"); + + return new SqlServerAppIdentityDbContext( + optionsBuilder.Options); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..088bb58 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.SqlServer.Identity +{ + public class SqlServerEShopAppIdentityDbBootstrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseSqlServer(configuration.GetConnectionString("IdentityConnection_SqlServer"))); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj new file mode 100644 index 0000000..9d151d0 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj @@ -0,0 +1,33 @@ + + + + netstandard2.1 + 80b8bc7f-cc13-45f4-967c-6c2b164a22e3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs new file mode 100644 index 0000000..b0b59db --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs @@ -0,0 +1,908 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200311151703_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs new file mode 100644 index 0000000..73c9a09 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs @@ -0,0 +1,450 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Baskets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true), + TransactionHash = table.Column(maxLength: 67, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Baskets", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Buyers", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Buyers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogBrands", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Brand = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogBrands", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Type = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + QuoteId = table.Column(nullable: true), + Status = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + PoDate = table.Column(nullable: true), + OrderDate = table.Column(nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Quotes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Status = table.Column(nullable: false), + Date = table.Column(nullable: false), + Expiry = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Quotes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "BasketItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + CatalogItemId = table.Column(nullable: false), + BasketId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BasketItems", x => x.Id); + table.ForeignKey( + name: "FK_BasketItems_Baskets_BasketId", + column: x => x.BasketId, + principalTable: "Baskets", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "BuyerPostalAddress", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(nullable: true), + PostalAddress_RecipientName = table.Column(maxLength: 255, nullable: true), + PostalAddress_Street = table.Column(maxLength: 180, nullable: true), + PostalAddress_City = table.Column(maxLength: 100, nullable: true), + PostalAddress_State = table.Column(maxLength: 60, nullable: true), + PostalAddress_Country = table.Column(maxLength: 90, nullable: true), + PostalAddress_ZipCode = table.Column(maxLength: 18, nullable: true), + BuyerId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_BuyerPostalAddress", x => x.Id); + table.ForeignKey( + name: "FK_BuyerPostalAddress_Buyers_BuyerId", + column: x => x.BuyerId, + principalTable: "Buyers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Catalog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Status = table.Column(nullable: false), + Gtin = table.Column(maxLength: 14, nullable: false), + GtinRegistryId = table.Column(nullable: true), + Name = table.Column(maxLength: 50, nullable: false), + Description = table.Column(nullable: true), + Price = table.Column(type: "decimal(18,2)", nullable: false), + Unit = table.Column(maxLength: 8, nullable: true), + CatalogTypeId = table.Column(nullable: false), + CatalogBrandId = table.Column(nullable: false), + PictureUri = table.Column(maxLength: 512, nullable: true), + PictureSmallUri = table.Column(maxLength: 512, nullable: true), + PictureMediumUri = table.Column(maxLength: 512, nullable: true), + PictureLargeUri = table.Column(maxLength: 512, nullable: true), + AttributeJson = table.Column(nullable: true), + Rank = table.Column(nullable: false), + Height = table.Column(nullable: false), + Width = table.Column(nullable: false), + Depth = table.Column(nullable: false), + Weight = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Catalog", x => x.Id); + table.ForeignKey( + name: "FK_Catalog_CatalogBrands_CatalogBrandId", + column: x => x.CatalogBrandId, + principalTable: "CatalogBrands", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Catalog_CatalogTypes_CatalogTypeId", + column: x => x.CatalogTypeId, + principalTable: "CatalogTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OrderItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Status = table.Column(nullable: false), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(maxLength: 50, nullable: true), + PoItemStatus = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + GoodsIssueDate = table.Column(nullable: true), + ActualEscrowReleaseDate = table.Column(nullable: true), + PlannedEscrowReleaseDate = table.Column(nullable: true), + IsEscrowReleased = table.Column(nullable: true), + QuantitySymbol = table.Column(maxLength: 32, nullable: true), + QuantityAddress = table.Column(maxLength: 43, nullable: true), + CurrencyValue = table.Column(maxLength: 100, nullable: true), + OrderId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OrderItems", x => x.Id); + table.ForeignKey( + name: "FK_OrderItems_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "QuoteItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + EscrowReleaseDate = table.Column(nullable: true), + QuantitySymbol = table.Column(nullable: true), + QuantityAddress = table.Column(nullable: true), + CurrencyValue = table.Column(nullable: true), + QuoteId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QuoteItems", x => x.Id); + table.ForeignKey( + name: "FK_QuoteItems_Quotes_QuoteId", + column: x => x.QuoteId, + principalTable: "Quotes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Stock", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CatalogItemId = table.Column(nullable: false), + Location = table.Column(maxLength: 50, nullable: false), + Quantity = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Stock", x => x.Id); + table.ForeignKey( + name: "FK_Stock_Catalog_CatalogItemId", + column: x => x.CatalogItemId, + principalTable: "Catalog", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_BasketItems_BasketId", + table: "BasketItems", + column: "BasketId"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerAddress", + table: "Baskets", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerId", + table: "Baskets", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_BuyerPostalAddress_BuyerId", + table: "BuyerPostalAddress", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerAddress", + table: "Buyers", + column: "BuyerAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerId", + table: "Buyers", + column: "BuyerId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogBrandId", + table: "Catalog", + column: "CatalogBrandId"); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogTypeId", + table: "Catalog", + column: "CatalogTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_OrderItems_OrderId", + table: "OrderItems", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerId", + table: "Orders", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_QuoteItems_QuoteId", + table: "QuoteItems", + column: "QuoteId"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerAddress", + table: "Quotes", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerId", + table: "Quotes", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Stock_CatalogItemId", + table: "Stock", + column: "CatalogItemId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BasketItems"); + + migrationBuilder.DropTable( + name: "BuyerPostalAddress"); + + migrationBuilder.DropTable( + name: "OrderItems"); + + migrationBuilder.DropTable( + name: "QuoteItems"); + + migrationBuilder.DropTable( + name: "Stock"); + + migrationBuilder.DropTable( + name: "Baskets"); + + migrationBuilder.DropTable( + name: "Buyers"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Quotes"); + + migrationBuilder.DropTable( + name: "Catalog"); + + migrationBuilder.DropTable( + name: "CatalogBrands"); + + migrationBuilder.DropTable( + name: "CatalogTypes"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..3a63067 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs @@ -0,0 +1,915 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200311172413_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs new file mode 100644 index 0000000..93dccf2 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BuyerWalletAddress", + table: "Buyers", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers", + column: "BuyerWalletAddress", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers"); + + migrationBuilder.DropColumn( + name: "BuyerWalletAddress", + table: "Buyers"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs new file mode 100644 index 0000000..13625ed --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs @@ -0,0 +1,905 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200331114826_RemoveBuyerAndWalletAddress")] + partial class RemoveBuyerAndWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs new file mode 100644 index 0000000..e205cba --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs @@ -0,0 +1,82 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class RemoveBuyerAndWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders"); + + // SQLite does not support drop column + // Create new temp table + migrationBuilder.CreateTable( + name: "TmpOrders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + QuoteId = table.Column(nullable: true), + Status = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + PoDate = table.Column(nullable: true), + OrderDate = table.Column(nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_TmpOrders", x => x.Id); + }); + + // Copy existing data to temp table, drop original and rename temp + migrationBuilder.Sql("INSERT INTO TmpOrders SELECT Id, QuoteId, Status, TransactionHash, BuyerId, CurrencyAddress, CurrencySymbol, PoNumber, PoType, BuyerWalletAddress, Sellerid, PoDate, OrderDate, BillTo_RecipientName, BillTo_Street, BillTo_City, BillTo_State, BillTo_Country, BillTo_ZipCode, ShipTo_RecipientName, ShipTo_Street, ShipTo_City, ShipTo_State, ShipTo_Country, ShipTo_ZipCode FROM Orders;"); + migrationBuilder.Sql("PRAGMA foreign_keys=\"0\"", true); + migrationBuilder.Sql("DROP TABLE Orders", true); + migrationBuilder.Sql("ALTER TABLE TmpOrders RENAME TO Orders", true); + migrationBuilder.Sql("PRAGMA foreign_keys=\"1\"", true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ApproverAddress", + table: "Orders", + type: "TEXT", + maxLength: 43, + nullable: true); + + migrationBuilder.AddColumn( + name: "BuyerAddress", + table: "Orders", + type: "TEXT", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs new file mode 100644 index 0000000..d2f514b --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs @@ -0,0 +1,925 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200403114507_CreateSettingsTable")] + partial class CreateSettingsTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs new file mode 100644 index 0000000..4cb9a78 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class CreateSettingsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(maxLength: 100, nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Settings_Key", + table: "Settings", + column: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql new file mode 100644 index 0000000..9027aa1 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -0,0 +1,291 @@ +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY, + "ProductVersion" TEXT NOT NULL +); + +CREATE TABLE "Baskets" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Baskets" PRIMARY KEY AUTOINCREMENT, + "BuyerId" TEXT NOT NULL, + "BuyerAddress" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL, + "TransactionHash" TEXT NULL +); + +CREATE TABLE "Buyers" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Buyers" PRIMARY KEY AUTOINCREMENT, + "BuyerId" TEXT NOT NULL, + "BuyerAddress" TEXT NULL +); + +CREATE TABLE "CatalogBrands" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_CatalogBrands" PRIMARY KEY AUTOINCREMENT, + "Brand" TEXT NOT NULL +); + +CREATE TABLE "CatalogTypes" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_CatalogTypes" PRIMARY KEY AUTOINCREMENT, + "Type" TEXT NOT NULL +); + +CREATE TABLE "Orders" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Orders" PRIMARY KEY AUTOINCREMENT, + "QuoteId" INTEGER NULL, + "Status" INTEGER NOT NULL, + "TransactionHash" TEXT NULL, + "BuyerId" TEXT NOT NULL, + "BuyerAddress" TEXT NULL, + "CurrencyAddress" TEXT NULL, + "CurrencySymbol" TEXT NULL, + "ApproverAddress" TEXT NULL, + "PoNumber" INTEGER NULL, + "PoType" INTEGER NOT NULL, + "BuyerWalletAddress" TEXT NULL, + "SellerId" TEXT NULL, + "PoDate" TEXT NULL, + "OrderDate" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL +); + +CREATE TABLE "Quotes" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Quotes" PRIMARY KEY AUTOINCREMENT, + "Status" INTEGER NOT NULL, + "Date" TEXT NOT NULL, + "Expiry" TEXT NOT NULL, + "TransactionHash" TEXT NULL, + "BuyerAddress" TEXT NULL, + "CurrencySymbol" TEXT NULL, + "CurrencyAddress" TEXT NULL, + "ApproverAddress" TEXT NULL, + "PoNumber" INTEGER NULL, + "PoType" INTEGER NOT NULL, + "BuyerWalletAddress" TEXT NULL, + "SellerId" TEXT NULL, + "BuyerId" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL +); + +CREATE TABLE "BasketItems" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_BasketItems" PRIMARY KEY AUTOINCREMENT, + "UnitPrice" decimal(18,2) NOT NULL, + "Quantity" INTEGER NOT NULL, + "CatalogItemId" INTEGER NOT NULL, + "BasketId" INTEGER NOT NULL, + CONSTRAINT "FK_BasketItems_Baskets_BasketId" FOREIGN KEY ("BasketId") REFERENCES "Baskets" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "BuyerPostalAddress" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_BuyerPostalAddress" PRIMARY KEY AUTOINCREMENT, + "Name" TEXT NULL, + "PostalAddress_RecipientName" TEXT NULL, + "PostalAddress_Street" TEXT NULL, + "PostalAddress_City" TEXT NULL, + "PostalAddress_State" TEXT NULL, + "PostalAddress_Country" TEXT NULL, + "PostalAddress_ZipCode" TEXT NULL, + "BuyerId" INTEGER NULL, + CONSTRAINT "FK_BuyerPostalAddress_Buyers_BuyerId" FOREIGN KEY ("BuyerId") REFERENCES "Buyers" ("Id") ON DELETE RESTRICT +); + +CREATE TABLE "Catalog" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Catalog" PRIMARY KEY AUTOINCREMENT, + "Status" INTEGER NOT NULL, + "Gtin" TEXT NOT NULL, + "GtinRegistryId" INTEGER NULL, + "Name" TEXT NOT NULL, + "Description" TEXT NULL, + "Price" decimal(18,2) NOT NULL, + "Unit" TEXT NULL, + "CatalogTypeId" INTEGER NOT NULL, + "CatalogBrandId" INTEGER NOT NULL, + "PictureUri" TEXT NULL, + "PictureSmallUri" TEXT NULL, + "PictureMediumUri" TEXT NULL, + "PictureLargeUri" TEXT NULL, + "AttributeJson" TEXT NULL, + "Rank" INTEGER NOT NULL, + "Height" INTEGER NOT NULL, + "Width" INTEGER NOT NULL, + "Depth" INTEGER NOT NULL, + "Weight" INTEGER NOT NULL, + CONSTRAINT "FK_Catalog_CatalogBrands_CatalogBrandId" FOREIGN KEY ("CatalogBrandId") REFERENCES "CatalogBrands" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_Catalog_CatalogTypes_CatalogTypeId" FOREIGN KEY ("CatalogTypeId") REFERENCES "CatalogTypes" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "OrderItems" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_OrderItems" PRIMARY KEY AUTOINCREMENT, + "Status" INTEGER NOT NULL, + "ItemOrdered_CatalogItemId" INTEGER NULL, + "ItemOrdered_Gtin" TEXT NULL, + "ItemOrdered_GtinRegistryId" INTEGER NULL, + "ItemOrdered_ProductName" TEXT NULL, + "ItemOrdered_PictureUri" TEXT NULL, + "UnitPrice" decimal(18,2) NOT NULL, + "Quantity" INTEGER NOT NULL, + "Unit" TEXT NULL, + "PoItemStatus" INTEGER NULL, + "PoItemNumber" INTEGER NULL, + "GoodsIssueDate" TEXT NULL, + "ActualEscrowReleaseDate" TEXT NULL, + "PlannedEscrowReleaseDate" TEXT NULL, + "IsEscrowReleased" INTEGER NULL, + "QuantitySymbol" TEXT NULL, + "QuantityAddress" TEXT NULL, + "CurrencyValue" TEXT NULL, + "OrderId" INTEGER NULL, + CONSTRAINT "FK_OrderItems_Orders_OrderId" FOREIGN KEY ("OrderId") REFERENCES "Orders" ("Id") ON DELETE RESTRICT +); + +CREATE TABLE "QuoteItems" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_QuoteItems" PRIMARY KEY AUTOINCREMENT, + "ItemOrdered_CatalogItemId" INTEGER NULL, + "ItemOrdered_Gtin" TEXT NULL, + "ItemOrdered_GtinRegistryId" INTEGER NULL, + "ItemOrdered_ProductName" TEXT NULL, + "ItemOrdered_PictureUri" TEXT NULL, + "UnitPrice" decimal(18,2) NOT NULL, + "Quantity" INTEGER NOT NULL, + "Unit" TEXT NULL, + "PoItemNumber" INTEGER NULL, + "EscrowReleaseDate" TEXT NULL, + "QuantitySymbol" TEXT NULL, + "QuantityAddress" TEXT NULL, + "CurrencyValue" TEXT NULL, + "QuoteId" INTEGER NULL, + CONSTRAINT "FK_QuoteItems_Quotes_QuoteId" FOREIGN KEY ("QuoteId") REFERENCES "Quotes" ("Id") ON DELETE RESTRICT +); + +CREATE TABLE "Stock" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Stock" PRIMARY KEY AUTOINCREMENT, + "CatalogItemId" INTEGER NOT NULL, + "Location" TEXT NOT NULL, + "Quantity" INTEGER NOT NULL, + CONSTRAINT "FK_Stock_Catalog_CatalogItemId" FOREIGN KEY ("CatalogItemId") REFERENCES "Catalog" ("Id") ON DELETE CASCADE +); + +CREATE INDEX "IX_BasketItems_BasketId" ON "BasketItems" ("BasketId"); + +CREATE INDEX "IX_Baskets_BuyerAddress" ON "Baskets" ("BuyerAddress"); + +CREATE INDEX "IX_Baskets_BuyerId" ON "Baskets" ("BuyerId"); + +CREATE INDEX "IX_BuyerPostalAddress_BuyerId" ON "BuyerPostalAddress" ("BuyerId"); + +CREATE UNIQUE INDEX "IX_Buyers_BuyerAddress" ON "Buyers" ("BuyerAddress"); + +CREATE UNIQUE INDEX "IX_Buyers_BuyerId" ON "Buyers" ("BuyerId"); + +CREATE INDEX "IX_Catalog_CatalogBrandId" ON "Catalog" ("CatalogBrandId"); + +CREATE INDEX "IX_Catalog_CatalogTypeId" ON "Catalog" ("CatalogTypeId"); + +CREATE INDEX "IX_OrderItems_OrderId" ON "OrderItems" ("OrderId"); + +CREATE INDEX "IX_Orders_BuyerAddress" ON "Orders" ("BuyerAddress"); + +CREATE INDEX "IX_Orders_BuyerId" ON "Orders" ("BuyerId"); + +CREATE INDEX "IX_QuoteItems_QuoteId" ON "QuoteItems" ("QuoteId"); + +CREATE INDEX "IX_Quotes_BuyerAddress" ON "Quotes" ("BuyerAddress"); + +CREATE INDEX "IX_Quotes_BuyerId" ON "Quotes" ("BuyerId"); + +CREATE INDEX "IX_Stock_CatalogItemId" ON "Stock" ("CatalogItemId"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311151703_InitialCreate', '3.1.2'); + +ALTER TABLE "Buyers" ADD "BuyerWalletAddress" TEXT NULL; + +CREATE UNIQUE INDEX "IX_Buyers_BuyerWalletAddress" ON "Buyers" ("BuyerWalletAddress"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311172413_BuyerWalletAddress', '3.1.2'); + +DROP INDEX "IX_Orders_BuyerAddress"; + +CREATE TABLE "TmpOrders" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_TmpOrders" PRIMARY KEY AUTOINCREMENT, + "QuoteId" INTEGER NULL, + "Status" INTEGER NOT NULL, + "TransactionHash" TEXT NULL, + "BuyerId" TEXT NOT NULL, + "CurrencyAddress" TEXT NULL, + "CurrencySymbol" TEXT NULL, + "PoNumber" INTEGER NULL, + "PoType" INTEGER NOT NULL, + "BuyerWalletAddress" TEXT NULL, + "SellerId" TEXT NULL, + "PoDate" TEXT NULL, + "OrderDate" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL +); + +INSERT INTO TmpOrders SELECT Id, QuoteId, Status, TransactionHash, BuyerId, CurrencyAddress, CurrencySymbol, PoNumber, PoType, BuyerWalletAddress, Sellerid, PoDate, OrderDate, BillTo_RecipientName, BillTo_Street, BillTo_City, BillTo_State, BillTo_Country, BillTo_ZipCode, ShipTo_RecipientName, ShipTo_Street, ShipTo_City, ShipTo_State, ShipTo_Country, ShipTo_ZipCode FROM Orders; + +PRAGMA foreign_keys="0" + +DROP TABLE Orders + +ALTER TABLE TmpOrders RENAME TO Orders + +PRAGMA foreign_keys="1" + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200331114826_RemoveBuyerAndWalletAddress', '3.1.2'); + +CREATE TABLE "Settings" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Settings" PRIMARY KEY AUTOINCREMENT, + "Key" TEXT NULL, + "Value" TEXT NULL +); + +CREATE INDEX "IX_Settings_Key" ON "Settings" ("Key"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200403114507_CreateSettingsTable', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs new file mode 100644 index 0000000..e3bf27f --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs @@ -0,0 +1,923 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + partial class SqliteCatalogContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Queries/CatalogQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/CatalogQueries.cs new file mode 100644 index 0000000..2f7e567 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/CatalogQueries.cs @@ -0,0 +1,72 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.Catalog.Queries +{ + public class CatalogQueries : ICatalogQueries + { + private readonly string _connectionString; + + public CatalogQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Rank" }; + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + string sortOrder = catalogQuerySpecification.SortDescending ? "desc" : "asc"; + catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; + + if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); + + using (var connection = new SqliteConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@searchText", catalogQuerySpecification.SearchText); + parameters.Add("@brandId", catalogQuerySpecification.BrandId); + parameters.Add("@typeId", catalogQuerySpecification.TypeId); + parameters.Add("@offset", catalogQuerySpecification.Offset); + parameters.Add("@fetch", catalogQuerySpecification.Fetch); + + + + var dbResults = await connection.QueryMultipleAsync( +@$" + SELECT Count(1) FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')); + + SELECT c.Id, c.[Name], c.CatalogBrandId, b.[Brand], c.CatalogTypeId, t.[Type], c.PictureUri, CAST(c.Price AS REAL) AS Price, c.[Rank] + FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')) + ORDER BY [{catalogQuerySpecification.SortBy}] {sortOrder} + LIMIT @fetch OFFSET @offset; +" + , parameters + ); + + var totalCount = dbResults.Read().Single(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, catalogQuerySpecification); + } + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs new file mode 100644 index 0000000..6d392e3 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs @@ -0,0 +1,74 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.Catalog.Queries +{ + public class OrderQueries: IOrderQueries + { + private readonly string _connectionString; + + public OrderQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new SqliteConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM [Orders] as o WHERE o.BuyerId = @buyerId; +SELECT + o.Id as OrderId, + o.QuoteId as QuoteId, + o.BuyerId, + o.TransactionHash, + o.OrderDate, + o.Status, + o.PoNumber, + o.PoType, + o.CurrencySymbol, + o.[BillTo_RecipientName], + o.[BillTo_ZipCode], + o.[ShipTo_RecipientName], + o.[ShipTo_ZipCode], + CAST((select sum(oi.Quantity * oi.UnitPrice) from OrderItems oi where oi.OrderId = o.Id) AS REAL) as Total, + CAST((select count(1) from OrderItems oi where oi.OrderId = o.Id) AS REAL) as ItemCount +FROM [Orders] as o +WHERE o.BuyerId = @buyerId +ORDER BY [{paginationArgs.SortBy}] {sortOrder} +LIMIT @fetch OFFSET @offset; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Queries/QuoteQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/QuoteQueries.cs new file mode 100644 index 0000000..8bd134d --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/QuoteQueries.cs @@ -0,0 +1,75 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.Catalog.Queries +{ + public class QuoteQueries: IQuoteQueries + { + private readonly string _connectionString; + + public QuoteQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new SqliteConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; +SELECT + q.Id as QuoteId, + q.BuyerAddress, + q.BuyerId, + q.TransactionHash, + q.Date as QuoteDate, + q.Status, + q.PoNumber, + q.PoType, + q.CurrencySymbol, + q.Expiry, + q.[BillTo_RecipientName], + q.[BillTo_ZipCode], + q.[ShipTo_RecipientName], + q.[ShipTo_ZipCode], + CAST((select sum(qi.Quantity * qi.UnitPrice) from QuoteItems qi where qi.QuoteId = q.Id) AS REAL) as Total, + CAST((select count(1) from QuoteItems qi where qi.QuoteId = q.Id) AS REAL) as ItemCount +FROM Quotes as q +WHERE q.BuyerId = @buyerId +ORDER BY [{paginationArgs.SortBy}] {sortOrder} +LIMIT @fetch OFFSET @offset; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs b/src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs new file mode 100644 index 0000000..86dd79c --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs @@ -0,0 +1,36 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog +{ + public class SqliteCatalogContext : CatalogContext + { + public SqliteCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + //config is in EntityFramework project + builder.ApplyConfigurationsFromAssembly(typeof(CatalogContext).Assembly); + } + } + + public class SqliteCatalogContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqliteCatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlite( + "Data Source=C:/temp/designtime_eshop_catalog.db;"); + + return new SqliteCatalogContext( + optionsBuilder.Options, + null); + } + } +} + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/SqliteEShopDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Catalog/SqliteEShopDbBootstrapper.cs new file mode 100644 index 0000000..87c2296 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/SqliteEShopDbBootstrapper.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.Sqlite.Catalog.Queries; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.Catalog +{ + public class SqliteEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + private const string ConnectionName = "CatalogConnection_Sqlite"; + + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext((serviceProvider, options) => + options.UseSqlite(configuration.GetConnectionString(ConnectionName))); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + string queryConnectionString = configuration.GetConnectionString(ConnectionName); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Common/Dapper/TypeHandlers/DateTimeOffsetHandler.cs b/src/Nethereum.eShop.Sqlite/Common/Dapper/TypeHandlers/DateTimeOffsetHandler.cs new file mode 100644 index 0000000..76d7e5c --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Common/Dapper/TypeHandlers/DateTimeOffsetHandler.cs @@ -0,0 +1,25 @@ +using Dapper; +using System; +using System.Data; + +namespace Nethereum.eShop.Sqlite.Common.Dapper.TypeHandlers +{ + public class DateTimeOffsetHandler : SqlMapper.TypeHandler + { + public static readonly DateTimeOffsetHandler Instance = new DateTimeOffsetHandler(); + + public override DateTimeOffset Parse(object value) + { + //2020-03-10 12:16:08.4610707+00:00 + return DateTimeOffset.TryParse((string)value, out DateTimeOffset date) ? date : DateTimeOffset.MinValue; + } + + public override void SetValue(IDbDataParameter parameter, DateTimeOffset value) + { + //2020-03-10 12:16:08.4610707+00:00 + //somewhat naive and optimistic approach! + //we're not yet implementing datetimeoffset parameters in queries + parameter.Value = value.ToString(); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs new file mode 100644 index 0000000..84b1788 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs @@ -0,0 +1,266 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Identity; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + [DbContext(typeof(SqliteAppIdentityDbContext))] + [Migration("20200311151709_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs new file mode 100644 index 0000000..e7d13ca --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs @@ -0,0 +1,217 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..5d5ba8e --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs @@ -0,0 +1,266 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Identity; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + [DbContext(typeof(SqliteAppIdentityDbContext))] + [Migration("20200311172419_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs new file mode 100644 index 0000000..a71e2f0 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql new file mode 100644 index 0000000..6352fc0 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -0,0 +1,92 @@ +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY, + "ProductVersion" TEXT NOT NULL +); + +CREATE TABLE "AspNetRoles" ( + "Id" TEXT NOT NULL CONSTRAINT "PK_AspNetRoles" PRIMARY KEY, + "Name" TEXT NULL, + "NormalizedName" TEXT NULL, + "ConcurrencyStamp" TEXT NULL +); + +CREATE TABLE "AspNetUsers" ( + "Id" TEXT NOT NULL CONSTRAINT "PK_AspNetUsers" PRIMARY KEY, + "UserName" TEXT NULL, + "NormalizedUserName" TEXT NULL, + "Email" TEXT NULL, + "NormalizedEmail" TEXT NULL, + "EmailConfirmed" INTEGER NOT NULL, + "PasswordHash" TEXT NULL, + "SecurityStamp" TEXT NULL, + "ConcurrencyStamp" TEXT NULL, + "PhoneNumber" TEXT NULL, + "PhoneNumberConfirmed" INTEGER NOT NULL, + "TwoFactorEnabled" INTEGER NOT NULL, + "LockoutEnd" TEXT NULL, + "LockoutEnabled" INTEGER NOT NULL, + "AccessFailedCount" INTEGER NOT NULL +); + +CREATE TABLE "AspNetRoleClaims" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY AUTOINCREMENT, + "RoleId" TEXT NOT NULL, + "ClaimType" TEXT NULL, + "ClaimValue" TEXT NULL, + CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserClaims" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY AUTOINCREMENT, + "UserId" TEXT NOT NULL, + "ClaimType" TEXT NULL, + "ClaimValue" TEXT NULL, + CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserLogins" ( + "LoginProvider" TEXT NOT NULL, + "ProviderKey" TEXT NOT NULL, + "ProviderDisplayName" TEXT NULL, + "UserId" TEXT NOT NULL, + CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey"), + CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserRoles" ( + "UserId" TEXT NOT NULL, + "RoleId" TEXT NOT NULL, + CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId"), + CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserTokens" ( + "UserId" TEXT NOT NULL, + "LoginProvider" TEXT NOT NULL, + "Name" TEXT NOT NULL, + "Value" TEXT NULL, + CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name"), + CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "AspNetRoleClaims" ("RoleId"); + +CREATE UNIQUE INDEX "RoleNameIndex" ON "AspNetRoles" ("NormalizedName"); + +CREATE INDEX "IX_AspNetUserClaims_UserId" ON "AspNetUserClaims" ("UserId"); + +CREATE INDEX "IX_AspNetUserLogins_UserId" ON "AspNetUserLogins" ("UserId"); + +CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "AspNetUserRoles" ("RoleId"); + +CREATE INDEX "EmailIndex" ON "AspNetUsers" ("NormalizedEmail"); + +CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311151709_InitialCreate', '3.1.2'); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311172419_BuyerWalletAddress', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs new file mode 100644 index 0000000..e84871a --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs @@ -0,0 +1,264 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Identity; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + [DbContext(typeof(SqliteAppIdentityDbContext))] + partial class SqliteAppIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs b/src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs new file mode 100644 index 0000000..062a30c --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.Sqlite.Identity +{ + public class SqliteAppIdentityDbContext : AppIdentityDbContext + { + public SqliteAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } + + public class SqliteAppIdentityContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqliteAppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlite( + "Data Source=C:/temp/designtime_eshop_app_identity.db;"); + + return new SqliteAppIdentityDbContext( + optionsBuilder.Options); + } + } + + +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..ba3e6bc --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,23 @@ +using Dapper; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; +using Nethereum.eShop.Sqlite.Common.Dapper.TypeHandlers; +using System; + +namespace Nethereum.eShop.Sqlite.Identity +{ + public class SqliteEShopAppIdentityDbBootstrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + SqlMapper.RemoveTypeMap(typeof(DateTimeOffset)); + SqlMapper.AddTypeHandler(DateTimeOffsetHandler.Instance); + + services.AddDbContext(options => + options.UseSqlite(configuration.GetConnectionString("IdentityConnection_Sqlite"))); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj b/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj new file mode 100644 index 0000000..4010510 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.1 + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index d3fd56e..bc7e62c 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -21,6 +21,28 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.Commerce.Contract EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebJobs", "WebJobs\WebJobs.csproj", "{C817D513-88E9-4721-A1EA-57EFE0FABCD5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.SqlServer", "Nethereum.eShop.SqlServer\Nethereum.eShop.SqlServer.csproj", "{658EAD99-D587-4105-9743-8DF2722858EA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.InMemory", "Nethereum.eShop.InMemory\Nethereum.eShop.InMemory.csproj", "{D7C0A1E5-3867-46AE-86F3-1436E514001B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.EntityFramework", "Nethereum.eShop.EntityFramework\Nethereum.eShop.EntityFramework.csproj", "{EEE22A14-93DE-4F3D-BE2F-748F40CD2706}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{757AB3ED-223F-45A7-8B6F-8BDA2CEB1EA2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{826D820C-C91E-4FBC-804E-1773C372CCA3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.Sqlite", "Nethereum.eShop.Sqlite\Nethereum.eShop.Sqlite.csproj", "{2914543B-FDB7-46A0-BB4D-A192765D4072}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.DbFactory", "Nethereum.eShop.DbFactory\Nethereum.eShop.DbFactory.csproj", "{173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.Migrations", "Nethereum.eShop.Migrations\Nethereum.eShop.Migrations.csproj", "{0E47F900-DBE4-4AFB-86A1-376303CECDFB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migration", "migration", "{487D2931-4813-4280-9FE1-E1AA7EA6ED34}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.MySql", "Nethereum.eShop.MySql\Nethereum.eShop.MySql.csproj", "{D607FEC2-2145-4660-A391-AE0737D5BE8B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,14 +73,53 @@ Global {C817D513-88E9-4721-A1EA-57EFE0FABCD5}.Debug|Any CPU.Build.0 = Debug|Any CPU {C817D513-88E9-4721-A1EA-57EFE0FABCD5}.Release|Any CPU.ActiveCfg = Release|Any CPU {C817D513-88E9-4721-A1EA-57EFE0FABCD5}.Release|Any CPU.Build.0 = Release|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Release|Any CPU.Build.0 = Release|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Release|Any CPU.Build.0 = Release|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Release|Any CPU.Build.0 = Release|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Release|Any CPU.Build.0 = Release|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Release|Any CPU.Build.0 = Release|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Release|Any CPU.Build.0 = Release|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {BA120028-FA8C-4EBD-8F2B-161F0C16A38C} = {757AB3ED-223F-45A7-8B6F-8BDA2CEB1EA2} + {F01D9C50-41B3-4975-AF7C-E6E5D4F24337} = {826D820C-C91E-4FBC-804E-1773C372CCA3} {3A6E7DC1-79B8-41DE-B9AD-A5E60F7C9CA7} = {11EFE1E8-51CF-4528-BC17-545478FE3BD0} {C22EF243-52C6-4976-8ADE-5504B40A37C3} = {5CC42B8D-582C-47C1-814A-E12B75FAC69E} {0281AF81-6DB5-48C4-9137-671D5E95E958} = {5CC42B8D-582C-47C1-814A-E12B75FAC69E} + {C817D513-88E9-4721-A1EA-57EFE0FABCD5} = {826D820C-C91E-4FBC-804E-1773C372CCA3} + {658EAD99-D587-4105-9743-8DF2722858EA} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {D7C0A1E5-3867-46AE-86F3-1436E514001B} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {2914543B-FDB7-46A0-BB4D-A192765D4072} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {0E47F900-DBE4-4AFB-86A1-376303CECDFB} = {487D2931-4813-4280-9FE1-E1AA7EA6ED34} + {487D2931-4813-4280-9FE1-E1AA7EA6ED34} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {D607FEC2-2145-4660-A391-AE0737D5BE8B} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEA2189-D111-472E-BA29-993E206C6CE3} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs index 25e352a..30a4af9 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs @@ -1,9 +1,94 @@ -namespace Nethereum.eShop.ApplicationCore.Entities +using MediatR; +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities { // This can easily be modified to be BaseEntity and public T Id to support different key types. // Using non-generic integer types for simplicity and to ease caching logic public class BaseEntity { - public int Id { get; set; } + int? _requestedHashCode; + int _Id; + public virtual int Id + { + get + { + return _Id; + } + protected set + { + _Id = value; + } + } + + private List _domainEvents; + public IReadOnlyCollection DomainEvents => _domainEvents?.AsReadOnly(); + + public void AddDomainEvent(INotification eventItem) + { + _domainEvents = _domainEvents ?? new List(); + _domainEvents.Add(eventItem); + } + + public void RemoveDomainEvent(INotification eventItem) + { + _domainEvents?.Remove(eventItem); + } + + public void ClearDomainEvents() + { + _domainEvents?.Clear(); + } + + public bool IsTransient() + { + return this.Id == default(Int32); + } + + public override bool Equals(object obj) + { + if (obj == null || !(obj is BaseEntity)) + return false; + + if (Object.ReferenceEquals(this, obj)) + return true; + + if (this.GetType() != obj.GetType()) + return false; + + BaseEntity item = (BaseEntity)obj; + + if (item.IsTransient() || this.IsTransient()) + return false; + else + return item.Id == this.Id; + } + + public override int GetHashCode() + { + if (!IsTransient()) + { + if (!_requestedHashCode.HasValue) + _requestedHashCode = this.Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) + + return _requestedHashCode.Value; + } + else + return base.GetHashCode(); + + } + public static bool operator ==(BaseEntity left, BaseEntity right) + { + if (Object.Equals(left, null)) + return (Object.Equals(right, null)) ? true : false; + else + return left.Equals(right); + } + + public static bool operator !=(BaseEntity left, BaseEntity right) + { + return !(left == right); + } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs index 68b9e29..8513bf0 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs @@ -6,6 +6,11 @@ namespace Nethereum.eShop.ApplicationCore.Entities.BasketAggregate { public class Basket : BaseEntity, IAggregateRoot { + public static Basket CreateForDeletion(int basketId) + { + return new Basket { Id = basketId }; + } + public string BuyerId { get; set; } /// diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs index 6ddd89b..0c97f42 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs @@ -15,6 +15,8 @@ public class Buyer : BaseEntity, IAggregateRoot // Expected To Be Ethereum Address public string BuyerAddress { get; private set; } + public string BuyerWalletAddress { get; private set; } + private Buyer() { // required by EF @@ -26,5 +28,10 @@ public Buyer(string identity) : this() BuyerId = identity; } + + public void SetWalletAddress(string walletAddress) + { + BuyerWalletAddress = walletAddress; + } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs new file mode 100644 index 0000000..5c6ca23 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs @@ -0,0 +1,27 @@ +using Nethereum.eShop.ApplicationCore.Interfaces; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + + public class Setting : BaseEntity, IAggregateRoot + { + public Setting(string key, string val) + { + Key = key; + Value = val; + } + + private Setting() + { + // for EF + } + + public string Key { get; private set; } + public string Value { get; private set; } + + public void SetValue(string val) + { + Value = val; + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs new file mode 100644 index 0000000..8b5826a --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class EShopConfigurationSettings + { + public static class Keys + { + public const string PREFIX = ""; + private static string PrefixedKey(string key) => $"{PREFIX}{key}"; + + public static readonly string BuyerWalletAddress = PrefixedKey("BuyerWalletAddress"); + public static readonly string PurchasingContractAddress = PrefixedKey("PurchasingContractAddress"); + public static readonly string CurrencySymbol = PrefixedKey("CurrencySymbol"); + public static readonly string CurrencyAddress = PrefixedKey("CurrencyAddress"); + public static readonly string QuantityAddress = PrefixedKey("QuantityAddress"); + + public static readonly string AddressRegistryAddress = PrefixedKey("AddressRegistryAddress"); + public static readonly string PoStorageAddress = PrefixedKey("PoStorageAddress"); + public static readonly string FundingAddress = PrefixedKey("FundingAddress"); + public static readonly string BusinessPartnerStorageAddress = PrefixedKey("BusinessPartnerStorageAddress"); + public static readonly string SellerAdminAddress = PrefixedKey("SellerAdminAddress"); + } + + public EShopConfigurationSettings(IEnumerable settings) + { + EShop = new EShopConfiguration(settings); + Seller = new SellerConfiguration(settings); + CreateFakePurchaseOrdersJob = new CreateFakePurchaseOrdersJobConfiguration(settings); + ProcessPurchaseOrderEvents = new ProcessPurchaseOrderEventsJobConfiguration(settings); + + BuyerWalletAddress = settings.GetString(Keys.BuyerWalletAddress); + PurchasingContractAddress = settings.GetString(Keys.PurchasingContractAddress); + CurrencySymbol = settings.GetString(Keys.CurrencySymbol); + CurrencyAddress = settings.GetString(Keys.CurrencyAddress); + + AddressRegistryAddress = settings.GetString(Keys.AddressRegistryAddress); + PoStorageAddress = settings.GetString(Keys.PoStorageAddress); + FundingAddress = settings.GetString(Keys.FundingAddress); + BusinessPartnerStorageAddress = settings.GetString(Keys.BusinessPartnerStorageAddress); + SellerAdminAddress = settings.GetString(Keys.SellerAdminAddress); + + } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateString(Keys.BuyerWalletAddress, BuyerWalletAddress); + settings.SetOrCreateString(Keys.PurchasingContractAddress, PurchasingContractAddress); + settings.SetOrCreateString(Keys.CurrencySymbol, CurrencySymbol); + settings.SetOrCreateString(Keys.CurrencyAddress, CurrencyAddress); + + settings.SetOrCreateString(Keys.AddressRegistryAddress, AddressRegistryAddress); + settings.SetOrCreateString(Keys.PoStorageAddress, PoStorageAddress); + settings.SetOrCreateString(Keys.FundingAddress, FundingAddress); + settings.SetOrCreateString(Keys.BusinessPartnerStorageAddress, BusinessPartnerStorageAddress); + settings.SetOrCreateString(Keys.SellerAdminAddress, SellerAdminAddress); + + EShop.UpdateSettings(settings); + Seller.UpdateSettings(settings); + CreateFakePurchaseOrdersJob.UpdateSettings(settings); + ProcessPurchaseOrderEvents.UpdateSettings(settings); + } + + public EShopConfiguration EShop { get; set; } + + public SellerConfiguration Seller { get; set; } + + public CreateFakePurchaseOrdersJobConfiguration CreateFakePurchaseOrdersJob { get; set; } + + public ProcessPurchaseOrderEventsJobConfiguration ProcessPurchaseOrderEvents { get; set; } + + public string BuyerWalletAddress { get; set; } + public string PurchasingContractAddress { get; set; } + public string CurrencySymbol { get; set; } + public string CurrencyAddress { get; set; } + + public string PoStorageAddress { get; set; } + + public string FundingAddress { get; set; } + + public string AddressRegistryAddress { get; set; } + + public string BusinessPartnerStorageAddress { get; set; } + + public string SellerAdminAddress { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs new file mode 100644 index 0000000..a557d99 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class CreateFakePurchaseOrdersJobConfiguration // Value Object + { + public CreateFakePurchaseOrdersJobConfiguration(IEnumerable settings) + { + Enabled = settings.GetBool("CreateFakePurchaseOrdersJob.Enabled", false); + } + + public bool Enabled { get; set; } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateBool("CreateFakePurchaseOrdersJob.Enabled", Enabled); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs new file mode 100644 index 0000000..b63d22c --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class EShopConfiguration // Value Object + { + public static class Keys + { + public const string PREFIX = "EShop"; + private static string PrefixedKey(string key) => $"{PREFIX}.{key}"; + + public static readonly string Id = PrefixedKey("Id"); + public static readonly string Description = PrefixedKey("Description"); + public static readonly string QuoteSigners = PrefixedKey("QuoteSigners"); + } + + public EShopConfiguration(IEnumerable settings) + { + Id = settings.GetString(Keys.Id); + Description = settings.GetString(Keys.Description); + QuoteSigners = settings.GetStringArray(Keys.QuoteSigners, Array.Empty()); + } + + public string Id { get; set; } + public string Description { get; set; } + public string[] QuoteSigners { get; set; } + + internal void UpdateSettings(List settings) + { + settings.SetOrCreateString(Keys.Id, Id); + settings.SetOrCreateString(Keys.Description, Description); + settings.SetOrCreateStringArray(Keys.QuoteSigners, QuoteSigners); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs new file mode 100644 index 0000000..0bc051e --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Numerics; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class ProcessPurchaseOrderEventsJobConfiguration // Value Object + { + public static class Keys + { + public const string PREFIX = "ProcessPurchaseOrderEventsJob"; + private static string PrefixedKey(string key) => $"{PREFIX}.{key}"; + + public static readonly string Enabled = PrefixedKey("Enabled"); + public static readonly string BlockProgressJsonFile = PrefixedKey("BlockProgressJsonFile"); + public static readonly string MinimumStartingBlock = PrefixedKey("MinimumStartingBlock"); + public static readonly string NumberOfBlocksPerBatch = PrefixedKey("NumberOfBlocksPerBatch"); + public static readonly string MinimumBlockConfirmations = PrefixedKey("MinimumBlockConfirmations"); + public static readonly string TimeoutMs = PrefixedKey("TimeoutMs"); + } + + public ProcessPurchaseOrderEventsJobConfiguration(IEnumerable settings) + { + Load(settings); + } + + private void Load(IEnumerable settings) + { + Enabled = settings.GetBool(Keys.Enabled, false); + BlockProgressJsonFile = settings.GetString(Keys.BlockProgressJsonFile); + MinimumStartingBlock = settings.GetBigIntegerOrNull(Keys.MinimumStartingBlock); + NumberOfBlocksPerBatch = settings.GetInt(Keys.NumberOfBlocksPerBatch); + MinimumBlockConfirmations = settings.GetInt(Keys.MinimumBlockConfirmations); + TimeoutMs = settings.GetInt(Keys.TimeoutMs); + } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateBool(Keys.Enabled, Enabled); + settings.SetOrCreateString(Keys.BlockProgressJsonFile, BlockProgressJsonFile); + settings.SetOrCreateNullableBigInteger(Keys.MinimumStartingBlock, MinimumStartingBlock); + settings.SetOrCreateInt(Keys.NumberOfBlocksPerBatch, NumberOfBlocksPerBatch); + settings.SetOrCreateInt(Keys.MinimumBlockConfirmations, MinimumBlockConfirmations); + settings.SetOrCreateInt(Keys.TimeoutMs, TimeoutMs); + } + + public bool Enabled { get; set; } + public string BlockProgressJsonFile { get; set; } + public BigInteger? MinimumStartingBlock { get; set; } + public int NumberOfBlocksPerBatch { get; set; } + public int MinimumBlockConfirmations { get; set; } + public int TimeoutMs { get; set; } + + + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs new file mode 100644 index 0000000..33d6eda --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class SellerConfiguration // Value Object + { + public static class Keys + { + public const string PREFIX = "Seller"; + private static string PrefixedKey(string key) => $"{PREFIX}.{key}"; + + public static readonly string Id = PrefixedKey("Id"); + public static readonly string Description = PrefixedKey("Description"); + public static readonly string AdminContractAddress = PrefixedKey("AdminContractAddress"); + } + + public SellerConfiguration(IEnumerable settings) + { + Id = settings.GetString(Keys.Id); + Description = settings.GetString(Keys.Description); + AdminContractAddress = settings.GetString(Keys.AdminContractAddress); + } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateString(Keys.Id, Id); + settings.SetOrCreateString(Keys.Description, Description); + settings.SetOrCreateString(Keys.AdminContractAddress, AdminContractAddress); + } + + public string Id { get; set; } + public string Description { get; set; } + public string AdminContractAddress { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs new file mode 100644 index 0000000..4ea6c28 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs @@ -0,0 +1,114 @@ +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public static class SettingExtensions + { + private static Setting GetSingle(this IEnumerable settings, string key) + => settings.FirstOrDefault(s => s.Key.Equals(key, System.StringComparison.OrdinalIgnoreCase)); + + public static string GetString(this IEnumerable settings, string key, string defaultValue = null) + { + var setting = settings.GetSingle(key); + return setting?.Value ?? defaultValue; + } + + public static string[] GetStringArray(this IEnumerable settings, string key, string[] defaultValue = null) + { + var setting = settings.GetSingle(key); + return setting?.Value?.Split(new char[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries) ?? defaultValue; + } + + public static int GetInt(this IEnumerable settings, string key, int defaultValue = 0) + { + var setting = settings.GetSingle(key); + if (setting == null) return defaultValue; + return int.TryParse(setting.Value, out int val) ? val : defaultValue; + } + + public static bool GetBool(this IEnumerable settings, string key, bool defaultValue = false) + { + var setting = settings.GetSingle(key); + if (setting == null) return defaultValue; + return bool.TryParse(setting.Value, out bool val) ? val : defaultValue; + } + + public static BigInteger? GetBigIntegerOrNull(this IEnumerable settings, string key) + { + var setting = settings.GetSingle(key); + if (setting == null) return null; + return BigInteger.TryParse(setting.Value, out BigInteger val) ? val : (BigInteger?)null; + } + + public static void SetOrCreateString(this List settings, string key, string val) + { + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, val)); + } + else + { + setting.SetValue(val); + } + } + + public static void SetOrCreateStringArray(this List settings, string key, string[] val, char delimeter = ',') + { + var setting = settings.GetSingle(key); + var valueAsString = val == null ? string.Empty : string.Join(delimeter, val); + + if (setting == null) + { + settings.Add(new Setting(key, valueAsString)); + } + else + { + setting.SetValue(valueAsString); + } + } + + public static void SetOrCreateBool(this List settings, string key, bool val) + { + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, val.ToString())); + } + else + { + setting.SetValue(val.ToString()); + } + } + + public static void SetOrCreateInt(this List settings, string key, int val) + { + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, val.ToString())); + } + else + { + setting.SetValue(val.ToString()); + } + } + + public static void SetOrCreateNullableBigInteger(this List settings, string key, BigInteger? val) + { + var valToWrite = val == null ? null : val.ToString(); + + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, valToWrite)); + } + else + { + setting.SetValue(valToWrite); + } + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs b/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs index 0cf2157..b21eb4c 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs @@ -18,17 +18,10 @@ public class Order : BaseEntity, IAggregateRoot public string BuyerId { get; set; } - /// - /// The Buyer Address - /// - public string BuyerAddress { get; set; } - public string CurrencyAddress { get; set; } public string CurrencySymbol { get; set; } - public string ApproverAddress { get; set; } - /// /// The Purhase Order Number /// @@ -79,17 +72,17 @@ private Order() // required by EF } - public Order(string buyerId, string buyerAddress, PostalAddress billTo, PostalAddress shipTo, List items) + public Order(string buyerId, string buyerWalletAddress, PostalAddress billTo, PostalAddress shipTo, List items) { Guard.Against.NullOrEmpty(buyerId, nameof(buyerId)); - Guard.Against.NullOrEmpty(buyerAddress, nameof(buyerAddress)); + Guard.Against.NullOrEmpty(buyerWalletAddress, nameof(buyerWalletAddress)); // TODO: Reinforce null address guards // Guard.Against.Null(billTo, nameof(billTo)); // Guard.Against.Null(shipTo, nameof(shipTo)); Guard.Against.Null(items, nameof(items)); BuyerId = buyerId; - BuyerAddress = buyerAddress; + BuyerWalletAddress = buyerWalletAddress; ShipTo = shipTo; _orderItems = items; } @@ -103,5 +96,10 @@ public decimal Total() } return total; } + + public int ItemCount() + { + return _orderItems == null ? 0 : _orderItems.Count; + } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs index b34ca02..3da8240 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs @@ -81,5 +81,15 @@ public decimal Total() return total; } + public int ItemCount() => _quoteItems == null ? 0 : _quoteItems.Count; + + public void SetConvertedToOrder(int orderNumber, long purchaseOrderNumber, string transactionHash) + { + //TODO: Add order number/id field + TransactionHash = transactionHash; + PoNumber = purchaseOrderNumber; + Status = QuoteStatus.Complete; + } + } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs index db21522..1e02a79 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs @@ -11,8 +11,14 @@ public RuleTreeSeed() Owner = null; } - public RuleTreeSeed(string psRuleTreeId, string psOriginUrl, string psOwner) + public RuleTreeSeed(int id) { + Id = id; + } + + public RuleTreeSeed(int id, string psRuleTreeId, string psOriginUrl, string psOwner) + { + Id = id; RuleTreeId = psRuleTreeId; RuleTreeOriginUrl = psOriginUrl; Owner = psOwner; diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs index 9f2b23d..d43a549 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; - -using Microsoft.Data.SqlClient; +using System.Data; namespace Nethereum.eShop.ApplicationCore.Entities.RulesEngine { @@ -12,7 +11,7 @@ public RulesDomainSeed() Init(); } - public RulesDomainSeed(SqlConnection conn, string table, HashSet cols) + public RulesDomainSeed(IDbConnection conn, string table, HashSet cols) { Init(); @@ -30,7 +29,7 @@ public RulesDomainSeed(HashSet types) #region Properties - public SqlConnection Connection { get; protected set; } + public IDbConnection Connection { get; protected set; } public string TargetTable { get; protected set; } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs index a2cef6d..f332285 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs @@ -10,11 +10,5 @@ public interface IAsyncRepository where T : BaseEntity, IAggregateRoot Task GetByIdAsync(int id); Task> ListAllAsync(); Task> ListAsync(ISpecification spec); - Task AddAsync(T entity); - Task UpdateAsync(T entity); - Task DeleteAsync(T entity); - Task CountAsync(ISpecification spec); - - DbSet DbSet { get; } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs new file mode 100644 index 0000000..ffadfbe --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs @@ -0,0 +1,16 @@ +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IBasketRepository : IRepository + { + Basket Add(Basket basket); + Basket Update(Basket basket); + void Delete(Basket basket); + void Delete(int basketId); + Task GetByIdWithItemsAsync(int id); + + Task GetByBuyerIdWithItemsAsync(string userName); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs new file mode 100644 index 0000000..4f73df9 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs @@ -0,0 +1,10 @@ +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface ICatalogContextSeeder + { + Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs index 2c1eaf6..a550314 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs @@ -1,10 +1,9 @@ using Nethereum.eShop.ApplicationCore.Entities; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { - public interface ICatalogItemRepository : IAsyncRepository + public interface ICatalogItemRepository : IAsyncRepository, IRepository { + } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs new file mode 100644 index 0000000..7bf29d7 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.Logging; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IContractDeploymentService + { + Task EnsureDeployedAsync(ILoggerFactory loggerFactory, CancellationToken cancellationToken = default); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs new file mode 100644 index 0000000..f921020 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IEShopDbBootstrapper + { + void AddDbContext(IServiceCollection services, IConfiguration configuration); + void AddRepositories(IServiceCollection services, IConfiguration configuration); + + void AddQueries(IServiceCollection services, IConfiguration configuration); + + Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default); + + void AddSeeders(IServiceCollection services, IConfiguration configuration); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs new file mode 100644 index 0000000..fccda4f --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IEShopIdentityDbBootstrapper + { + void AddDbContext(IServiceCollection services, IConfiguration configuration); + + void AddIdentityStores(IdentityBuilder identityBuilder, IServiceCollection services); + + Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs index 8faa284..06e6b60 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs @@ -4,8 +4,10 @@ namespace Nethereum.eShop.ApplicationCore.Interfaces { - public interface IOrderRepository : IAsyncRepository + public interface IOrderRepository : IAsyncRepository, IRepository { + Order Add(Order order); + Order Update(Order order); Task GetByIdWithItemsAsync(int id); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs index d6bdcdb..9bef1ce 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs @@ -1,10 +1,16 @@ using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using System.Collections.Generic; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { - public interface IQuoteRepository : IAsyncRepository + public interface IQuoteRepository : IAsyncRepository, IRepository { + Quote Add(Quote quote); + Quote Update(Quote quote); + Task GetByIdWithItemsAsync(int id); + + Task> GetQuotesRequiringPurchaseOrderAsync(); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IRepository.cs new file mode 100644 index 0000000..1c81032 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IRepository.cs @@ -0,0 +1,7 @@ +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IRepository + { + IUnitOfWork UnitOfWork { get; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs new file mode 100644 index 0000000..e1c1ec4 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs @@ -0,0 +1,14 @@ +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + + public interface ISettingRepository : IAsyncRepository, IRepository + { + Setting Add(Setting setting); + Setting Update(Setting setting); + Task GetEShopConfigurationSettingsAsync(); + Task UpdateAsync(EShopConfigurationSettings configurationSettings); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IUnitOfWork.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IUnitOfWork.cs new file mode 100644 index 0000000..5daa1fa --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IUnitOfWork.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IUnitOfWork : IDisposable + { + Task SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); + Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs new file mode 100644 index 0000000..b25ac79 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + public class CatalogExcerpt + { + public int Id { get; set; } + public string Name { get; set; } + public string Brand { get; set; } + public string PictureUri { get; set; } + public decimal Price { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs new file mode 100644 index 0000000..e55d525 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs @@ -0,0 +1,11 @@ +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + public class GetCatalogItemsSpecification: PaginationArgs + { + public int? BrandId { get; set; } + + public int? TypeId { get; set; } + + public string SearchText { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs new file mode 100644 index 0000000..64144c9 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + + public interface ICatalogQueries + { + Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs new file mode 100644 index 0000000..a3bb415 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Orders +{ + public interface IOrderQueries + { + Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs new file mode 100644 index 0000000..e2dc1ca --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs @@ -0,0 +1,32 @@ +using System; + +namespace Nethereum.eShop.ApplicationCore.Queries.Orders +{ + public class OrderExcerpt + { + public int OrderId { get; set; } + public int? QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public DateTimeOffset OrderDate { get; set; } + + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } + + + + +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs b/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs new file mode 100644 index 0000000..8560b9f --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Queries +{ + // TODO: Consider adding properties for Item Count, Page Number, Next Index etc + public class PaginatedResult where TModel : class + { + public int Offset { get; private set; } + + public int Fetch { get; private set; } + + public int TotalCount { get; private set; } + + public IEnumerable Data { get; private set; } + + public string SortedBy { get; private set; } + + public PaginatedResult(int offset, int fetch, int totalCount, IEnumerable data, string sortedBy) + { + Offset = offset; + Fetch = fetch; + TotalCount = totalCount; + Data = data; + SortedBy = sortedBy; + } + + public PaginatedResult(int totalCount, IEnumerable data, PaginationArgs paginatedQuery) + { + TotalCount = totalCount; + Data = data; + Offset = paginatedQuery.Offset; + Fetch = paginatedQuery.Fetch; + SortedBy = paginatedQuery.SortBy; + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs b/src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs new file mode 100644 index 0000000..153ceb7 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs @@ -0,0 +1,13 @@ +namespace Nethereum.eShop.ApplicationCore.Queries +{ + public class PaginationArgs + { + public int Offset { get; set; } = 0; + + public int Fetch { get; set; } = 50; + + public string SortBy { get; set; } + + public bool SortDescending { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs new file mode 100644 index 0000000..4341b36 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Quotes +{ + public interface IQuoteQueries + { + Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs new file mode 100644 index 0000000..2834992 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs @@ -0,0 +1,33 @@ +using System; + +namespace Nethereum.eShop.ApplicationCore.Queries.Quotes +{ + public class QuoteExcerpt + { + public int QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset QuoteDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } + + + + +} diff --git a/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs b/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs index 3a8b15e..b5029e5 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs @@ -1,45 +1,39 @@ -using Nethereum.eShop.ApplicationCore.Interfaces; -using System.Threading.Tasks; +using Ardalis.GuardClauses; +using Nethereum.eShop.ApplicationCore.Interfaces; using System.Collections.Generic; -using Nethereum.eShop.ApplicationCore.Specifications; using System.Linq; -using Ardalis.GuardClauses; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Services { public class BasketService : IBasketService { - private readonly IAsyncRepository _basketRepository; + private readonly IBasketRepository _basketRepository; private readonly IAppLogger _logger; - public BasketService(IAsyncRepository basketRepository, - IAppLogger logger) + public BasketService(IBasketRepository basketRepository, IAppLogger logger) { - _basketRepository = basketRepository; + _basketRepository = basketRepository ?? throw new System.ArgumentNullException(nameof(basketRepository)); _logger = logger; } public async Task AddItemToBasket(int basketId, int catalogItemId, decimal price, int quantity = 1) { - var basket = await _basketRepository.GetByIdAsync(basketId); - + var basket = await _basketRepository.GetByIdWithItemsAsync(basketId).ConfigureAwait(false); basket.AddItem(catalogItemId, price, quantity); - - await _basketRepository.UpdateAsync(basket); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } public async Task DeleteBasketAsync(int basketId) { - var basket = await _basketRepository.GetByIdAsync(basketId); - await _basketRepository.DeleteAsync(basket); + _basketRepository.Delete(basketId); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } public async Task GetBasketItemCountAsync(string userName) { Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basketSpec = new BasketWithItemsSpecification(userName); - var basket = (await _basketRepository.ListAsync(basketSpec)).FirstOrDefault(); + var basket = await _basketRepository.GetByBuyerIdWithItemsAsync(userName).ConfigureAwait(false); if (basket == null) { _logger.LogInformation($"No basket found for {userName}"); @@ -53,7 +47,7 @@ public async Task GetBasketItemCountAsync(string userName) public async Task SetQuantities(int basketId, Dictionary quantities) { Guard.Against.Null(quantities, nameof(quantities)); - var basket = await _basketRepository.GetByIdAsync(basketId); + var basket = await _basketRepository.GetByIdWithItemsAsync(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); foreach (var item in basket.Items) { @@ -64,20 +58,19 @@ public async Task SetQuantities(int basketId, Dictionary quantities } } basket.RemoveEmptyItems(); - await _basketRepository.UpdateAsync(basket); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } public async Task TransferBasketAsync(string anonymousId, string userName) { Guard.Against.NullOrEmpty(anonymousId, nameof(anonymousId)); Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basketSpec = new BasketWithItemsSpecification(anonymousId); - var basket = (await _basketRepository.ListAsync(basketSpec)).FirstOrDefault(); + var basket = await _basketRepository.GetByBuyerIdWithItemsAsync(anonymousId).ConfigureAwait(false); if (basket == null) return; basket.BuyerId = userName; // TODO: populate from buyer entity basket.BuyerAddress = ""; - await _basketRepository.UpdateAsync(basket); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs b/src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs new file mode 100644 index 0000000..ff6963f --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs @@ -0,0 +1,119 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Nethereum.Commerce.Contracts.Deployment; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.Web3.Accounts; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Services +{ + public class ContractDeploymentService : IContractDeploymentService + { + private readonly IConfiguration _configuration; + private readonly ISettingRepository _settingRepository; + + public ContractDeploymentService(IConfiguration configuration, ISettingRepository settingRepository) + { + _configuration = configuration; + _settingRepository = settingRepository; + } + + public async Task EnsureDeployedAsync(ILoggerFactory loggerFactory, CancellationToken cancellationToken = default) + { + var logger = loggerFactory.CreateLogger(); + + var dbBasedConfig = await _settingRepository.GetEShopConfigurationSettingsAsync().ConfigureAwait(false); + + if (string.IsNullOrWhiteSpace(dbBasedConfig.BuyerWalletAddress) == false) return; + + if (string.IsNullOrEmpty(dbBasedConfig.EShop.Id)) + { + dbBasedConfig.EShop.Id = "Nethereum.EShop"; + dbBasedConfig.EShop.Description = "Nethereum EShop"; + } + + if (string.IsNullOrEmpty(dbBasedConfig.Seller.Id)) + { + dbBasedConfig.Seller.Id = "Nethereum.EShop.Seller.1"; + dbBasedConfig.Seller.Description = "Nethereum.EShop Seller One"; + } + + if (string.IsNullOrEmpty(dbBasedConfig.CurrencySymbol)) + { + dbBasedConfig.CurrencySymbol = "DAI"; + } + + if(dbBasedConfig.EShop.QuoteSigners?.Length == 0) + { + //TODO: remove this hardcoded stuff + dbBasedConfig.EShop.QuoteSigners = new[] { "0x32A555F2328e85E489f9a5f03669DC820CE7EBe9", "0x94618601FE6cb8912b274E5a00453949A57f8C1e" }; + } + + if(dbBasedConfig.ProcessPurchaseOrderEvents.TimeoutMs < 1) + { + dbBasedConfig.ProcessPurchaseOrderEvents.TimeoutMs = 3600000; + } + + if(dbBasedConfig.ProcessPurchaseOrderEvents.NumberOfBlocksPerBatch < 1) + { + dbBasedConfig.ProcessPurchaseOrderEvents.NumberOfBlocksPerBatch = 100; + } + + if(dbBasedConfig.ProcessPurchaseOrderEvents.MinimumBlockConfirmations < 1) + { + dbBasedConfig.ProcessPurchaseOrderEvents.MinimumBlockConfirmations = 12; + } + + if (string.IsNullOrEmpty(dbBasedConfig.ProcessPurchaseOrderEvents.BlockProgressJsonFile)) + { + dbBasedConfig.ProcessPurchaseOrderEvents.BlockProgressJsonFile = "c:/temp/po_blockprogress.json"; + } + + var url = _configuration["EthereumRpcUrl"]; + var privateKey = _configuration["AccountPrivateKey"]; + + var web3 = new Web3.Web3(new Account(privateKey), url); + + var contractDeploymentConfig = new ContractNewDeploymentConfig + { + AlsoDeployMockContracts = true, + Eshop = new Commerce.Contracts.BusinessPartnerStorage.ContractDefinition.Eshop + { + EShopId = dbBasedConfig.EShop.Id, + EShopDescription = dbBasedConfig.EShop.Description, + QuoteSigners = dbBasedConfig.EShop.QuoteSigners.ToList() + }, + Seller = new Commerce.Contracts.BusinessPartnerStorage.ContractDefinition.Seller + { + SellerId = dbBasedConfig.Seller.Id, + SellerDescription = dbBasedConfig.Seller.Description, + AdminContractAddress = dbBasedConfig.Seller.AdminContractAddress + } + }; + + var contractDeployment = new ContractDeployment(web3, contractDeploymentConfig, logger); + + await contractDeployment.InitializeAsync().ConfigureAwait(false); + + dbBasedConfig.BuyerWalletAddress = contractDeployment.BuyerWalletService.ContractHandler.ContractAddress; + dbBasedConfig.PurchasingContractAddress = contractDeployment.PurchasingService.ContractHandler.ContractAddress; + dbBasedConfig.CurrencyAddress = contractDeployment.MockDaiService.ContractHandler.ContractAddress; + + dbBasedConfig.AddressRegistryAddress = contractDeployment.AddressRegistryService?.ContractHandler?.ContractAddress; + dbBasedConfig.FundingAddress = contractDeployment.FundingService?.ContractHandler?.ContractAddress; + dbBasedConfig.PoStorageAddress = contractDeployment.PoStorageService?.ContractHandler?.ContractAddress; + dbBasedConfig.BusinessPartnerStorageAddress = contractDeployment.BusinessPartnerStorageService?.ContractHandler?.ContractAddress; + dbBasedConfig.SellerAdminAddress = contractDeployment.SellerAdminService?.ContractHandler?.ContractAddress; + + // if deployment has succeeded, presume it's ok to enable web jobs + dbBasedConfig.CreateFakePurchaseOrdersJob.Enabled = true; + dbBasedConfig.ProcessPurchaseOrderEvents.Enabled = true; + + await _settingRepository.UpdateAsync(dbBasedConfig); + + await _settingRepository.UnitOfWork.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs index 59a8f38..569643a 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs @@ -1,10 +1,8 @@ using Ardalis.GuardClauses; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; -using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; using System; using System.Collections.Generic; using System.Linq; @@ -14,48 +12,54 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class OrderService : IOrderService { - private readonly IAsyncRepository _orderRepository; - private readonly IAsyncRepository _quoteRepository; - private readonly IAsyncRepository _itemRepository; + private readonly IOrderRepository _orderRepository; + private readonly IQuoteRepository _quoteRepository; - public OrderService(IAsyncRepository quoteRepository, - IAsyncRepository itemRepository, - IAsyncRepository orderRepository) + public OrderService(IOrderRepository orderRepository, IQuoteRepository quoteRepository) { - _orderRepository = orderRepository; - _quoteRepository = quoteRepository; - _itemRepository = itemRepository; + _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); + _quoteRepository = quoteRepository ?? throw new ArgumentNullException(nameof(quoteRepository)); } public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) { // TODO: write purchase order values to order // TODO: Ensure po values are consistent with quote - int quoteId = (int)purchaseOrder.QuoteId; + var quote = await _quoteRepository.GetByIdWithItemsAsync(quoteId).ConfigureAwait(false); + Guard.Against.NullQuote(quoteId, quote); - var spec = new QuoteWithItemsSpecification(quoteId); + List orderItems = MapQuoteItemsToOrderItems(quote); + Order order = MapQuoteToOrder(transactionHash, purchaseOrder, quote, orderItems); - var quotes = await _quoteRepository.ListAsync(spec); - var quote = quotes.FirstOrDefault(); + quote.SetConvertedToOrder(order.Id, (long)purchaseOrder.PoNumber, transactionHash); - Guard.Against.NullQuote(quoteId, quote); + _orderRepository.Add(order); + await _orderRepository.UnitOfWork.SaveChangesAsync().ConfigureAwait(false); + } + + private static List MapQuoteItemsToOrderItems(Quote quote) + { var items = new List(); foreach (var item in quote.QuoteItems) { var orderItem = new OrderItem(item.ItemOrdered, item.UnitPrice, item.Quantity); items.Add(orderItem); } - var order = new Order(quote.BuyerId, purchaseOrder.BuyerAddress, quote.BillTo, quote.ShipTo, items); + + return items; + } + + private static Order MapQuoteToOrder(string transactionHash, Po purchaseOrder, Quote quote, List items) + { + var order = new Order(quote.BuyerId, purchaseOrder.BuyerWalletAddress, quote.BillTo, quote.ShipTo, items); order.QuoteId = quote.Id; order.PoDate = DateTimeOffset.FromUnixTimeSeconds((long)purchaseOrder.PoCreateDate); order.PoType = (int)purchaseOrder.PoType; - order.ApproverAddress = purchaseOrder.ApproverAddress; // TODO: define if we should have BuyerId and BuyerAddress // the po will have the address, the quote will have the buyer order.BuyerId = quote.BuyerId; - order.BuyerAddress = purchaseOrder.BuyerAddress; order.BuyerWalletAddress = purchaseOrder.BuyerWalletAddress; order.CurrencyAddress = purchaseOrder.CurrencyAddress; @@ -64,7 +68,7 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) order.Status = OrderStatus.Pending; order.TransactionHash = transactionHash; - foreach(var poItem in purchaseOrder.PoItems) + foreach (var poItem in purchaseOrder.PoItems) { var orderItem = quote.QuoteItems.ElementAtOrDefault((int)poItem.PoItemNumber - 1); if (orderItem == null) continue; @@ -78,11 +82,7 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) orderItem.EscrowReleaseDate = DateTimeOffset.FromUnixTimeSeconds((long)poItem.PlannedEscrowReleaseDate); } - await _orderRepository.AddAsync(order); - quote.TransactionHash = transactionHash; - quote.PoNumber = (long)purchaseOrder.PoNumber; - quote.Status = QuoteStatus.Complete; - await _quoteRepository.UpdateAsync(quote); + return order; } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs deleted file mode 100644 index 6436513..0000000 --- a/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Ardalis.GuardClauses; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -using Nethereum.eShop.ApplicationCore.Interfaces; -using System; -using System.Threading.Tasks; - -namespace Nethereum.eShop.ApplicationCore.Services -{ - public class PurchaseOrderService : IPurchaseOrderService - { - private readonly IAsyncRepository _basketRepository; - private readonly IAsyncRepository _itemRepository; - - public PurchaseOrderService( - IAsyncRepository basketRepository, - IAsyncRepository itemRepository) - { - _basketRepository = basketRepository; - _itemRepository = itemRepository; - } - - public async Task CreateOrderAsync(int basketId, PostalAddress billingAddress, PostalAddress shippingAddress) - { - // TODO: - // write address to buyer, to be looked up on po creation - // Create purchase order on chain - // using basket to populate - // we need the buyer nonce - - var basket = await _basketRepository.GetByIdAsync(basketId); - Guard.Against.NullBasket(basketId, basket); - - throw new NotImplementedException(); - //var items = new List(); - //foreach (var item in basket.Items) - //{ - - - // var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId); - // var itemOrdered = new CatalogItemOrdered(catalogItem.Id, catalogItem.Name, catalogItem.PictureUri); - // var orderItem = new OrderItem(itemOrdered, item.UnitPrice, item.Quantity); - // items.Add(orderItem); - //} - //var order = new Order(basket.BuyerId, billingAddress, shippingAddress, items); - - //await _orderRepository.AddAsync(order); - } - } -} diff --git a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs index 0d04163..ea8042b 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs @@ -13,21 +13,21 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class QuoteService : IQuoteService { - private readonly IAsyncRepository _quoteRepository; - private readonly IAsyncRepository _basketRepository; - private readonly IAsyncRepository _itemRepository; + private readonly IBasketRepository _basketRepository; + private readonly ICatalogItemRepository _itemRepository; + private readonly IQuoteRepository _quoteRepository; private readonly IRulesEngineService _rulesEngineService; public QuoteService( - IAsyncRepository basketRepository, - IAsyncRepository itemRepository, - IAsyncRepository orderRepository, + IBasketRepository basketRepository, + ICatalogItemRepository itemRepository, + IQuoteRepository quoteRepository, IRulesEngineService rulesEngineService) { - _quoteRepository = orderRepository; - _basketRepository = basketRepository; - _itemRepository = itemRepository; - _rulesEngineService = rulesEngineService; + _basketRepository = basketRepository ?? throw new ArgumentNullException(nameof(basketRepository)); + _itemRepository = itemRepository ?? throw new ArgumentNullException(nameof(itemRepository)); + _quoteRepository = quoteRepository ?? throw new ArgumentNullException(nameof(quoteRepository)); + _rulesEngineService = rulesEngineService ?? throw new ArgumentNullException(nameof(rulesEngineService)); } public async Task CreateQuoteAsync(int basketId) @@ -40,7 +40,7 @@ public async Task CreateQuoteAsync(int basketId) // Create purchase order // reserve stock? - var basket = await _basketRepository.GetByIdAsync(basketId); + var basket = await _basketRepository.GetByIdWithItemsAsync(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); var quoteItems = await MapAsync(basket); @@ -64,12 +64,14 @@ public async Task CreateQuoteAsync(int basketId) // NOTE: Should there be any indication of minor issues to the user? } } - catch (RuleTreeException ruleTreeEx) + catch (RuleTreeException) { // NOTE: Should we redirect the user to an error page? } - await _quoteRepository.AddAsync(quote); + _quoteRepository.Add(quote); + + await _quoteRepository.UnitOfWork.SaveChangesAsync().ConfigureAwait(false); } private async Task> ExecuteRules(Quote targetQuote) @@ -122,7 +124,7 @@ private async Task> MapAsync(Basket basket) var items = new List(); foreach (var item in basket.Items) { - var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId); + var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId).ConfigureAwait(false); var itemOrdered = new CatalogItemExcerpt( catalogItem.Id, catalogItem.Gtin, catalogItem.GtinRegistryId, catalogItem.Name, catalogItem.PictureUri); diff --git a/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs b/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs index 00a5c8f..dd2fc19 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs @@ -29,11 +29,10 @@ public RulesEngineService(IRuleTreeCache ruleTreeRepo, _reportRepository = reportRepo; } - public async Task CreateRulesDomainAsync(RulesDomainSeed domainSeed) + public Task CreateRulesDomainAsync(RulesDomainSeed domainSeed) { // TODO: Do all the work to help initialize the RuleTree - - return new RulesDomain(domainSeed); + return Task.FromResult(new RulesDomain(domainSeed)); } public async Task CreateRuleTreeAsync(RulesDomain domain, RuleTreeSeed origin) @@ -47,17 +46,17 @@ public async Task CreateRuleTreeAsync(RulesDomain domain, RuleTreeSeed return new RuleTree(origin); } - public async Task ExecuteAsync(RuleTree targetRuleTree, RuleTreeRecord targetRecord) + public Task ExecuteAsync(RuleTree targetRuleTree, RuleTreeRecord targetRecord) { // TODO: Do all the work to execute the RuleTree - and return a report? Random rnd = new Random(); - var Report = new RuleTreeReport(new RuleTreeSeed()) { Id = rnd.Next() }; + var Report = new RuleTreeReport(new RuleTreeSeed( rnd.Next())); // NOTE: To be determined where reports will be stored in the database, if at all // await _reportRepository.AddAsync(Report).ConfigureAwait(false); - return Report; + return Task.FromResult(Report); } public async Task GetQuoteRuleTree() @@ -65,7 +64,7 @@ public async Task GetQuoteRuleTree() var sBizRulesUrl = _rulesEngineInitializer.GetQuoteBizRulesFileUrl(); RuleTreeSeed quoteTreeSeed = - new RuleTreeSeed("QuoteTree", sBizRulesUrl, "default") { Id = 1 }; + new RuleTreeSeed(1, "QuoteTree", sBizRulesUrl, "default"); var RuleTreeIsCached = await _ruleTreeRepository.ContainsAsync(quoteTreeSeed.Id).ConfigureAwait(false); @@ -86,7 +85,7 @@ public async Task GetQuoteItemRuleTree() var sBizRulesUrl = _rulesEngineInitializer.GetQuoteItemBizRulesFileUrl(); RuleTreeSeed quoteItemTreeSeed = - new RuleTreeSeed("QuoteItemTree", sBizRulesUrl, "default") { Id = 2 }; + new RuleTreeSeed(2, "QuoteItemTree", sBizRulesUrl, "default"); var RuleTreeIsCached = await _ruleTreeRepository.ContainsAsync(quoteItemTreeSeed.Id).ConfigureAwait(false); @@ -107,11 +106,11 @@ public async Task> ListRuleTreeCacheAsync() return await _ruleTreeRepository.ListAllAsync().ConfigureAwait(false); } - public async Task Transform(object originalObject) + public Task Transform(object originalObject) { // TODO: Convert the object to a RuleTreeRecord - using reflection? - return new RuleTreeRecord(); + return Task.FromResult(new RuleTreeRecord()); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs b/src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs deleted file mode 100644 index 03cf530..0000000 --- a/src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Nethereum.eShop.ApplicationCore.Entities; - -namespace Nethereum.eShop.ApplicationCore.Specifications -{ - - public class CatalogFilterSpecification : BaseSpecification - { - public CatalogFilterSpecification(int? brandId, int? typeId, string searchText = null) - : base(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && - (!typeId.HasValue || i.CatalogTypeId == typeId) && - (searchText == null || (i.Name.Contains(searchText) || i.CatalogBrand.Brand.Contains(searchText)))) - { - } - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/GeneralCache.cs b/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs similarity index 63% rename from src/Nethereum.eShop/Infrastructure/Data/GeneralCache.cs rename to src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs index 7032e5f..9b36c13 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/GeneralCache.cs +++ b/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.Infrastructure.Cache { /// /// @@ -23,31 +23,33 @@ public GeneralCache() _cache = new Dictionary(); } - public virtual async Task ContainsAsync(int id) + public virtual Task ContainsAsync(int id) { - return _cache.ContainsKey(id); + return Task.FromResult(_cache.ContainsKey(id)); } - public virtual async Task GetByIdAsync(int id) + public virtual Task GetByIdAsync(int id) { - return _cache[id]; + return Task.FromResult(_cache[id]); } - public async Task> ListAllAsync() + public virtual Task> ListAllAsync() { - return _cache.Values.ToList(); + IReadOnlyList list = _cache.Values.ToList().AsReadOnly(); + return Task.FromResult(list); } - public async Task AddAsync(T entity) + public virtual Task AddAsync(T entity) { _cache[entity.Id] = entity; - return entity; + return Task.FromResult(entity); } - public async Task DeleteAsync(T entity) + public Task DeleteAsync(T entity) { if (_cache.ContainsKey(entity.Id)) _cache.Remove(entity.Id); + return Task.CompletedTask; } } } \ No newline at end of file diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs deleted file mode 100644 index 23af718..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -using System.Reflection; - -namespace Nethereum.eShop.Infrastructure.Data -{ - - public class CatalogContext : DbContext - { - public CatalogContext(DbContextOptions options) : base(options) - { - } - - public DbSet Buyers { get; set; } - - public DbSet Baskets { get; set; } - - public DbSet BasketItems { get; set; } - public DbSet CatalogItems { get; set; } - public DbSet CatalogBrands { get; set; } - public DbSet CatalogTypes { get; set; } - public DbSet StockItems { get; set; } - - public DbSet Quotes { get; set; } - - public DbSet QuoteItems { get; set; } - - public DbSet Orders { get; set; } - public DbSet OrderItems { get; set; } - - protected override void OnModelCreating(ModelBuilder builder) - { - base.OnModelCreating(builder); - builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); - } - - - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogImportDto.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogImportDto.cs deleted file mode 100644 index 606abb2..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogImportDto.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Nethereum.eShop.ApplicationCore.Entities; -using System.Collections.Generic; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public class CatalogImportDto - { - public List CatalogBrands { get; set; } = new List(); - public List CatalogTypes { get; set; } = new List(); - public List CatalogItems { get; set; } = new List(); - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs deleted file mode 100644 index ab584ac..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Interfaces; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public class CatalogItemRepository : EfRepository, ICatalogItemRepository - { - public CatalogItemRepository(CatalogContext dbContext) : base(dbContext) - { - } - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs deleted file mode 100644 index 67b156b..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace Nethereum.eShop.Infrastructure.Data.Config -{ - public static class EntityBuilderExtensions - { - private const int Hash = 67; - private const int Address = 43; - private const int BigIntegerLength = 100; - - public static PropertyBuilder IsPrice(this PropertyBuilder prop) - { - return prop.HasColumnType("decimal(18,2)"); - } - - public static PropertyBuilder IsHash(this PropertyBuilder prop) - { - return prop.HasMaxLength(Hash); - } - - public static PropertyBuilder IsAddress(this PropertyBuilder prop) - { - return prop.HasMaxLength(Address); - } - - public static PropertyBuilder IsBigInteger(this PropertyBuilder prop) - { - return prop.HasMaxLength(BigIntegerLength); - } - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs deleted file mode 100644 index a1e65d4..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; - -namespace Nethereum.eShop.Infrastructure.Data.Config -{ - public class OrderItemConfiguration : IEntityTypeConfiguration - { - public void Configure(EntityTypeBuilder builder) - { - builder.OwnsOne(i => i.ItemOrdered, io => - { - io.WithOwner(); - - io.Property(cio => cio.ProductName) - .HasMaxLength(50) - .IsRequired(); - }); - - builder.Property(oi => oi.UnitPrice) - .IsRequired(true) - .IsPrice(); - } - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs deleted file mode 100644 index d81d321..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Interfaces; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Infrastructure.Data -{ - /// - /// "There's some repetition here - couldn't we have some the sync methods call the async?" - /// https://blogs.msdn.microsoft.com/pfxteam/2012/04/13/should-i-expose-synchronous-wrappers-for-asynchronous-methods/ - /// - /// - public class EfRepository : IAsyncRepository where T : BaseEntity, IAggregateRoot - { - protected readonly CatalogContext _dbContext; - - public DbSet DbSet => _dbContext.Set(); - - public EfRepository(CatalogContext dbContext) - { - _dbContext = dbContext; - } - - public virtual async Task GetByIdAsync(int id) - { - return await _dbContext.Set().FindAsync(id); - } - - public async Task> ListAllAsync() - { - return await _dbContext.Set().ToListAsync(); - } - - public async Task> ListAsync(ISpecification spec) - { - return await ApplySpecification(spec).ToListAsync(); - } - - public async Task CountAsync(ISpecification spec) - { - return await ApplySpecification(spec).CountAsync(); - } - - public async Task AddAsync(T entity) - { - await _dbContext.Set().AddAsync(entity); - await _dbContext.SaveChangesAsync(); - - return entity; - } - - public async Task UpdateAsync(T entity) - { - _dbContext.Entry(entity).State = EntityState.Modified; - await _dbContext.SaveChangesAsync(); - } - - public async Task DeleteAsync(T entity) - { - _dbContext.Set().Remove(entity); - await _dbContext.SaveChangesAsync(); - } - - private IQueryable ApplySpecification(ISpecification spec) - { - return SpecificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), spec); - } - } -} \ No newline at end of file diff --git a/src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs b/src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs deleted file mode 100644 index cbe5aa9..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public interface ICatalogContextSeeder - { - Task SeedAsync(CatalogContext catalogContext, ILoggerFactory loggerFactory, int? retry = 0); - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs deleted file mode 100644 index 6fa3c37..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -using Nethereum.eShop.ApplicationCore.Interfaces; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public class QuoteRepository : EfRepository, IQuoteRepository - { - public QuoteRepository(CatalogContext dbContext) : base(dbContext) - { - } - - public Task GetByIdWithItemsAsync(int id) - { - return _dbContext.Quotes - .Include(o => o.QuoteItems) - .Include($"{nameof(Quote.QuoteItems)}.{nameof(QuoteItem.ItemOrdered)}") - .FirstOrDefaultAsync(x => x.Id == id); - } - } -} diff --git a/src/Nethereum.eShop/Infrastructure/Data/RuleTreeCache.cs b/src/Nethereum.eShop/Infrastructure/Data/RuleTreeCache.cs deleted file mode 100644 index 185632d..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/RuleTreeCache.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public class RuleTreeCache : GeneralCache, IRuleTreeCache - { - public RuleTreeCache() - {} - - public async Task GetByIdAsync(string id) - { - return new RuleTree(new RuleTreeSeed()); - } - - public async Task GetLastRuleTreeCreatedAsync() - { - return new RuleTree(new RuleTreeSeed()); - } - } -} diff --git a/src/Nethereum.eShop/Nethereum.eShop.csproj b/src/Nethereum.eShop/Nethereum.eShop.csproj index e69c8d5..7877732 100644 --- a/src/Nethereum.eShop/Nethereum.eShop.csproj +++ b/src/Nethereum.eShop/Nethereum.eShop.csproj @@ -7,19 +7,13 @@ - + + - + - - - - - - - diff --git a/src/Web/.config/dotnet-tools.json b/src/Web/.config/dotnet-tools.json index f2de671..56e0950 100644 --- a/src/Web/.config/dotnet-tools.json +++ b/src/Web/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "3.1.1", + "version": "3.1.2", "commands": [ "dotnet-ef" ] diff --git a/src/Web/ApplyDbMigrations.bat b/src/Web/ApplyDbMigrations.bat deleted file mode 100644 index cdca914..0000000 --- a/src/Web/ApplyDbMigrations.bat +++ /dev/null @@ -1,4 +0,0 @@ -rem Applying Migrations (update db) -dotnet build -dotnet ef database update --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --no-build -dotnet ef database update --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --no-build \ No newline at end of file diff --git a/src/Web/Controllers/QuoteController.cs b/src/Web/Controllers/QuoteController.cs index 695b09e..9d6176e 100644 --- a/src/Web/Controllers/QuoteController.cs +++ b/src/Web/Controllers/QuoteController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nethereum.eShop.Web.Features.MyQuotes; -using Nethereum.eShop.Web.Features.OrderDetails; using Nethereum.eShop.Web.Features.QuoteDetails; using System.Threading.Tasks; diff --git a/src/Web/CreateInitialDbMigration.bat b/src/Web/CreateInitialDbMigration.bat deleted file mode 100644 index ff41e43..0000000 --- a/src/Web/CreateInitialDbMigration.bat +++ /dev/null @@ -1,4 +0,0 @@ -rem Create First Migration aka InitialCreate -dotnet build -dotnet ef migrations add InitialCreate --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --output-dir ..\Nethereum.eShop\Infrastructure\Data\Migrations --no-build -dotnet ef migrations add InitialCreate --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --output-dir ..\Nethereum.eShop\Infrastructure\Identity\Migrations --no-build \ No newline at end of file diff --git a/src/Web/Features/MyOrders/GetMyOrders.cs b/src/Web/Features/MyOrders/GetMyOrders.cs index 24d65a4..e56c1c6 100644 --- a/src/Web/Features/MyOrders/GetMyOrders.cs +++ b/src/Web/Features/MyOrders/GetMyOrders.cs @@ -4,7 +4,7 @@ namespace Nethereum.eShop.Web.Features.MyOrders { - public class GetMyOrders : IRequest> + public class GetMyOrders : IRequest> { public string UserName { get; set; } diff --git a/src/Web/Features/MyOrders/GetMyOrdersHandler.cs b/src/Web/Features/MyOrders/GetMyOrdersHandler.cs index 10c1286..4c85c71 100644 --- a/src/Web/Features/MyOrders/GetMyOrdersHandler.cs +++ b/src/Web/Features/MyOrders/GetMyOrdersHandler.cs @@ -1,6 +1,7 @@ -using MediatR; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; +using AutoMapper; +using MediatR; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.Web.ViewModels; using System.Collections.Generic; using System.Linq; @@ -9,35 +10,34 @@ namespace Nethereum.eShop.Web.Features.MyOrders { - public class GetMyOrdersHandler : IRequestHandler> + public class GetMyOrdersHandler : IRequestHandler> { - private readonly IOrderRepository _orderRepository; + private readonly static Mapper _mapper; + static GetMyOrdersHandler() + { + var config = new MapperConfiguration(cfg => cfg.AddProfile()); + _mapper = new Mapper(config); + } - public GetMyOrdersHandler(IOrderRepository orderRepository) + private readonly IOrderQueries _orderQueries; + + public GetMyOrdersHandler(IOrderQueries orderQueries) { - _orderRepository = orderRepository; + _orderQueries = orderQueries; } - public async Task> Handle(GetMyOrders request, CancellationToken cancellationToken) + public async Task> Handle(GetMyOrders request, CancellationToken cancellationToken) { - var specification = new CustomerOrdersWithItemsSpecification(request.UserName); - var orders = await _orderRepository.ListAsync(specification); + var orders = await _orderQueries.GetByBuyerIdAsync(request.UserName, new PaginationArgs { Fetch = 100, SortDescending = true }); + return orders.Data.Select(o => _mapper.Map(o)); + } + } - return orders.Select(o => new OrderViewModel - { - OrderDate = o.OrderDate, - OrderItems = o.OrderItems?.Select(oi => new OrderItemViewModel() - { - PictureUrl = oi.ItemOrdered.PictureUri, - ProductId = oi.ItemOrdered.CatalogItemId, - ProductName = oi.ItemOrdered.ProductName, - UnitPrice = oi.UnitPrice, - Units = oi.Quantity - }).ToList(), - OrderNumber = o.Id, - ShippingAddress = o.ShipTo, - Total = o.Total() - }); + public class OrderExcerptProfile : Profile + { + public OrderExcerptProfile() + { + this.CreateMap(); } } } diff --git a/src/Web/Features/MyQuotes/GetMyQuotes.cs b/src/Web/Features/MyQuotes/GetMyQuotes.cs index 431c7a8..c18ec19 100644 --- a/src/Web/Features/MyQuotes/GetMyQuotes.cs +++ b/src/Web/Features/MyQuotes/GetMyQuotes.cs @@ -4,7 +4,7 @@ namespace Nethereum.eShop.Web.Features.MyQuotes { - public class GetMyQuotes : IRequest> + public class GetMyQuotes : IRequest> { public string UserName { get; set; } diff --git a/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs b/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs index dff2578..a9aa950 100644 --- a/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs +++ b/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs @@ -1,6 +1,7 @@ -using MediatR; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; +using AutoMapper; +using MediatR; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.Web.ViewModels; using System.Collections.Generic; using System.Linq; @@ -9,38 +10,35 @@ namespace Nethereum.eShop.Web.Features.MyQuotes { - public class GetMyQuotesHandler : IRequestHandler> + + public class GetMyQuotesHandler : IRequestHandler> { - private readonly IQuoteRepository _quoteRepository; + private readonly static Mapper _mapper; + static GetMyQuotesHandler() + { + var config = new MapperConfiguration(cfg => cfg.AddProfile()); + _mapper = new Mapper(config); + } + + private readonly IQuoteQueries _quoteQueries; - public GetMyQuotesHandler(IQuoteRepository quoteRepository) + public GetMyQuotesHandler(IQuoteQueries quoteRepository) { - _quoteRepository = quoteRepository; + _quoteQueries = quoteRepository; } - public async Task> Handle(GetMyQuotes request, CancellationToken cancellationToken) + public async Task> Handle(GetMyQuotes request, CancellationToken cancellationToken) { - var specification = new CustomerQuotesWithItemsSpecification(request.UserName); - var orders = await _quoteRepository.ListAsync(specification); + var quotes = await _quoteQueries.GetByBuyerIdAsync(request.UserName, new PaginationArgs { Fetch = 100, SortDescending = true }); + return quotes.Data.Select(excerpt => _mapper.Map(excerpt)); + } + } - return orders.Select(o => new QuoteViewModel - { - QuoteDate = o.Date, - QuoteItems = o.QuoteItems?.Select(oi => new QuoteItemViewModel() - { - PictureUrl = oi.ItemOrdered.PictureUri, - ProductId = oi.ItemOrdered.CatalogItemId, - ProductName = oi.ItemOrdered.ProductName, - UnitPrice = oi.UnitPrice, - Units = oi.Quantity - }).ToList(), - QuoteId = o.Id, - Status = o.Status.ToString(), - TransactionHash = o.TransactionHash, - ShipTo = o.ShipTo, - BillTo = o.BillTo, - Total = o.Total() - }); + public class QuoteExcerptProfile : Profile + { + public QuoteExcerptProfile() + { + this.CreateMap(); } } } diff --git a/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs b/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs index 3aaab70..97a83c9 100644 --- a/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs +++ b/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs @@ -19,8 +19,7 @@ public GetOrderDetailsHandler(IOrderRepository orderRepository) public async Task Handle(GetOrderDetails request, CancellationToken cancellationToken) { - var customerOrders = await _orderRepository.ListAsync(new CustomerOrdersWithItemsSpecification(request.UserName)); - var order = customerOrders.FirstOrDefault(o => o.Id == request.OrderId); + var order = await _orderRepository.GetByIdWithItemsAsync(request.OrderId); if (order == null) { diff --git a/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs b/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs index c4e30c5..c0f2d5a 100644 --- a/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs +++ b/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs @@ -19,8 +19,7 @@ public GetQuoteDetailsHandler(IQuoteRepository quoteRepository) public async Task Handle(GetQuoteDetails request, CancellationToken cancellationToken) { - var customerQuotes = await _quoteRepository.ListAsync(new CustomerQuotesWithItemsSpecification(request.UserName)); - var quote = customerQuotes.FirstOrDefault(o => o.Id == request.QuoteId); + var quote = await _quoteRepository.GetByIdWithItemsAsync(request.QuoteId); if (quote == null) { diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 93cc851..2f842ef 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -7,6 +7,8 @@ using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Microsoft.Extensions.Configuration; namespace Nethereum.eShop.Web { @@ -20,16 +22,23 @@ public async static Task Main(string[] args) using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; + var loggerFactory = services.GetRequiredService(); + var configuration = scope.ServiceProvider.GetRequiredService(); try { - var catalogContext = services.GetRequiredService(); + await services.GetRequiredService().EnsureCreatedAsync(services, configuration); + await services.GetRequiredService().EnsureCreatedAsync(services, configuration); + var catalogContextSeeder = services.GetRequiredService(); - await catalogContextSeeder.SeedAsync(catalogContext, loggerFactory); + await catalogContextSeeder.SeedAsync(loggerFactory); var userManager = services.GetRequiredService>(); var roleManager = services.GetRequiredService>(); await AppIdentityDbContextSeed.SeedAsync(userManager, roleManager); + + var contractDeploymentService = services.GetRequiredService(); + await contractDeploymentService.EnsureDeployedAsync(loggerFactory); } catch (Exception ex) { diff --git a/src/Web/Services/BasketViewModelService.cs b/src/Web/Services/BasketViewModelService.cs index 9d7f64f..4607fbb 100644 --- a/src/Web/Services/BasketViewModelService.cs +++ b/src/Web/Services/BasketViewModelService.cs @@ -1,23 +1,20 @@ -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Pages.Basket; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Nethereum.eShop.Web.Services { public class BasketViewModelService : IBasketViewModelService { - private readonly IAsyncRepository _basketRepository; + private readonly IBasketRepository _basketRepository; private readonly IUriComposer _uriComposer; - private readonly IAsyncRepository _itemRepository; + private readonly ICatalogItemRepository _itemRepository; - public BasketViewModelService(IAsyncRepository basketRepository, - IAsyncRepository itemRepository, + public BasketViewModelService(IBasketRepository basketRepository, + ICatalogItemRepository itemRepository, IUriComposer uriComposer) { _basketRepository = basketRepository; @@ -27,8 +24,7 @@ public BasketViewModelService(IAsyncRepository basketRepository, public async Task GetOrCreateBasketForUser(string userName) { - var basketSpec = new BasketWithItemsSpecification(userName); - var basket = (await _basketRepository.ListAsync(basketSpec)).FirstOrDefault(); + var basket = await _basketRepository.GetByBuyerIdWithItemsAsync(userName); if (basket == null) { @@ -50,7 +46,8 @@ private async Task CreateBasketForUser(string userId) { // TODO: populate from buyer entity var basket = new Basket() { BuyerId = userId, BuyerAddress = string.Empty }; - await _basketRepository.AddAsync(basket); + _basketRepository.Add(basket); + await _basketRepository.UnitOfWork.SaveEntitiesAsync(); return new BasketViewModel() { diff --git a/src/Web/Services/CatalogItemViewModelService.cs b/src/Web/Services/CatalogItemViewModelService.cs index fceaca3..9afde99 100644 --- a/src/Web/Services/CatalogItemViewModelService.cs +++ b/src/Web/Services/CatalogItemViewModelService.cs @@ -8,9 +8,9 @@ namespace Nethereum.eShop.Web.Services { public class CatalogItemViewModelService : ICatalogItemViewModelService { - private readonly IAsyncRepository _catalogItemRepository; + private readonly ICatalogItemRepository _catalogItemRepository; - public CatalogItemViewModelService(IAsyncRepository catalogItemRepository) + public CatalogItemViewModelService(ICatalogItemRepository catalogItemRepository) { _catalogItemRepository = catalogItemRepository; } @@ -25,7 +25,7 @@ public async Task UpdateCatalogItem(CatalogItemViewModel viewModel) updatedCatalogItem.Name = viewModel.Name; updatedCatalogItem.Price = viewModel.Price; - await _catalogItemRepository.UpdateAsync(updatedCatalogItem); + await _catalogItemRepository.UnitOfWork.SaveEntitiesAsync(); } } } diff --git a/src/Web/Services/CatalogViewModelService.cs b/src/Web/Services/CatalogViewModelService.cs index 9bbe85e..2420234 100644 --- a/src/Web/Services/CatalogViewModelService.cs +++ b/src/Web/Services/CatalogViewModelService.cs @@ -2,7 +2,7 @@ using Microsoft.Extensions.Logging; using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.Web.ViewModels; using System; using System.Collections.Generic; @@ -18,20 +18,20 @@ namespace Nethereum.eShop.Web.Services public class CatalogViewModelService : ICatalogViewModelService { private readonly ILogger _logger; - private readonly ICatalogItemRepository _itemRepository; + private readonly ICatalogQueries _catalogQueries; private readonly IAsyncRepository _brandRepository; private readonly IAsyncRepository _typeRepository; private readonly IUriComposer _uriComposer; public CatalogViewModelService( ILoggerFactory loggerFactory, - ICatalogItemRepository itemRepository, + ICatalogQueries catalogQueries, IAsyncRepository brandRepository, IAsyncRepository typeRepository, IUriComposer uriComposer) { _logger = loggerFactory.CreateLogger(); - _itemRepository = itemRepository; + _catalogQueries = catalogQueries; _brandRepository = brandRepository; _typeRepository = typeRepository; _uriComposer = uriComposer; @@ -41,15 +41,17 @@ public async Task GetCatalogItems(int pageIndex, int item { _logger.LogInformation("GetCatalogItems called."); - var filterSpecification = new CatalogFilterSpecification(brandId, typeId, searchText); - var filterPaginatedSpecification = - new CatalogFilterPaginatedSpecification(itemsPage * pageIndex, itemsPage, brandId, typeId, searchText); - // the implementation below using ForEach and Count. We need a List. - var itemsOnPage = await _itemRepository.ListAsync(filterPaginatedSpecification); - var totalItems = await _itemRepository.CountAsync(filterSpecification); + var itemsOnPage = await _catalogQueries.GetCatalogItemsAsync(new GetCatalogItemsSpecification + { + BrandId = brandId, + TypeId = typeId, + Fetch = itemsPage, + SearchText = searchText, + Offset = (pageIndex * itemsPage) + }); - foreach (var itemOnPage in itemsOnPage) + foreach (var itemOnPage in itemsOnPage.Data) { itemOnPage.PictureUri = _uriComposer.ComposePicUri(itemOnPage.PictureUri); } @@ -58,13 +60,13 @@ public async Task GetCatalogItems(int pageIndex, int item var vm = new CatalogIndexViewModel() { - CatalogItems = itemsOnPage.Select(i => new CatalogItemViewModel() + CatalogItems = itemsOnPage.Data.Select(i => new CatalogItemViewModel() { Id = i.Id, Name = i.Name, PictureUri = i.PictureUri, Price = i.Price, - Brand = brands.FirstOrDefault(b => b.Id == i.CatalogBrandId)?.Brand + Brand = i.Brand }), Brands = await GetBrands(), Types = await GetTypes(), @@ -73,9 +75,9 @@ public async Task GetCatalogItems(int pageIndex, int item PaginationInfo = new PaginationInfoViewModel() { ActualPage = pageIndex, - ItemsPerPage = itemsOnPage.Count, - TotalItems = totalItems, - TotalPages = int.Parse(Math.Ceiling(((decimal)totalItems / itemsPage)).ToString()) + ItemsPerPage = itemsOnPage.Data.Count(), + TotalItems = itemsOnPage.TotalCount, + TotalPages = int.Parse(Math.Ceiling(((decimal)itemsOnPage.TotalCount / itemsPage)).ToString()) } }; diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index b65cff0..c1e5ecb 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -6,24 +6,27 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.ApplicationModels; -using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.DbFactory; +using Nethereum.eShop.EntityFramework.Catalog.Cache; +using Nethereum.eShop.EntityFramework.Identity; +using Nethereum.eShop.Infrastructure.Cache; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Services; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Diagnostics.HealthChecks; -using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Mime; +using System.Threading.Tasks; namespace Nethereum.eShop.Web { @@ -39,105 +42,63 @@ public Startup(IConfiguration configuration) public void ConfigureDevelopmentServices(IServiceCollection services) { - var inMemoryDbConfig = Configuration["use-in-memory-db"]; - // Default to in memory db - // if sql is required - set "use-in-memory-db" to false in appsettings, command line or user secrets - var inMemory = string.IsNullOrEmpty(inMemoryDbConfig) ? true : bool.Parse(inMemoryDbConfig); - - if (inMemory) - { - // use in-memory database - ConfigureInMemoryDatabases(services); - } - else - { - // use real database - ConfigureProductionServices(services); - } - - } - - private void ConfigureInMemoryDatabases(IServiceCollection services) - { - // use in-memory database - services.AddDbContext(c => - c.UseInMemoryDatabase("Catalog")); - - // Add Identity DbContext - services.AddDbContext(options => - options.UseInMemoryDatabase("Identity")); - - ConfigureServices(services); + ConfigureProductionServices(services); } public void ConfigureProductionServices(IServiceCollection services) { - // use real database - // Requires LocalDB which can be installed with SQL Server Express 2016 - // https://www.microsoft.com/en-us/download/details.aspx?id=54284 + IEShopDbBootstrapper dbBootstrapper = EShopDbBootstrapper.CreateDbBootstrapper(Configuration); + services.AddSingleton(dbBootstrapper); + dbBootstrapper.AddDbContext(services, Configuration); - // migrations require a .net tool - // ensure to install the dotnet-ef tool - 3.1.1 - // dotnet tool install --global dotnet-ef --version 3.1.1 + IEShopIdentityDbBootstrapper identityDbBootstrapper = EShopDbBootstrapper.CreateAppIdentityDbBootstrapper(Configuration); + services.AddSingleton(identityDbBootstrapper); + identityDbBootstrapper.AddDbContext(services, Configuration); - /* - * A batch file can be run to create the migration and update the DB - See CreateAndApplyDbMigrations.bat in the root of the Web project - */ - - services.AddDbContext((serviceProvider, options) => - options.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"))); - - // Add Identity DbContext - services.AddDbContext(options => - options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection"))); - - ConfigureServices(services); + ConfigureServices(services, dbBootstrapper, identityDbBootstrapper); } public void ConfigureTestingServices(IServiceCollection services) { - ConfigureInMemoryDatabases(services); + Configuration["CatalogDbProvider"] = "InMemory"; + Configuration["AppIdentityDbProvider"] = "InMemory"; + ConfigureProductionServices(services); } // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) + public void ConfigureServices( + IServiceCollection services, IEShopDbBootstrapper dbBootstrapper, IEShopIdentityDbBootstrapper eShopIdentityDbBootstrapper) { ConfigureCookieSettings(services); - CreateIdentityIfNotCreated(services); + CreateIdentityIfNotCreated(services, eShopIdentityDbBootstrapper); services.AddMediatR(typeof(BasketViewModelService).Assembly); + dbBootstrapper.AddQueries(services, Configuration); + dbBootstrapper.AddRepositories(services, Configuration); + services.AddScoped(typeof(IAsyncCache<>), typeof(GeneralCache<>)); - services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.Configure(Configuration); var catalogSettings = Configuration.Get(); + services.AddSingleton(catalogSettings); services.AddSingleton(new UriComposer(catalogSettings)); - var catalogContextSeeder = string.IsNullOrEmpty(catalogSettings.CatalogSeedJsonFile) ? - (ICatalogContextSeeder)new HardCodedCatalogContextSeeder() : - (ICatalogContextSeeder)new JsonCatalogContextSeeder(catalogSettings.CatalogSeedJsonFile); + dbBootstrapper.AddSeeders(services, Configuration); - services.AddSingleton(catalogContextSeeder); + services.AddScoped(); var rulesEngineSettings = Configuration.Get(); @@ -185,7 +146,7 @@ public void ConfigureServices(IServiceCollection services) _services = services; // used to debug registered services } - private static void CreateIdentityIfNotCreated(IServiceCollection services) + private static void CreateIdentityIfNotCreated(IServiceCollection services, IEShopIdentityDbBootstrapper eShopIdentityDbBootstrapper) { var sp = services.BuildServiceProvider(); using (var scope = sp.CreateScope()) @@ -194,10 +155,9 @@ private static void CreateIdentityIfNotCreated(IServiceCollection services) .GetService>(); if(existingUserManager == null) { - services.AddIdentity() - .AddDefaultUI() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); + var builder = services.AddIdentity().AddDefaultUI(); + eShopIdentityDbBootstrapper.AddIdentityStores(builder, services); + builder.AddDefaultTokenProviders(); } } } @@ -284,4 +244,5 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) }); } } + } diff --git a/src/Web/ViewModels/OrderExcerptViewModel.cs b/src/Web/ViewModels/OrderExcerptViewModel.cs new file mode 100644 index 0000000..4c7d5f9 --- /dev/null +++ b/src/Web/ViewModels/OrderExcerptViewModel.cs @@ -0,0 +1,31 @@ +using System; + +namespace Nethereum.eShop.Web.ViewModels +{ + public class OrderExcerptViewModel + { + public int OrderId { get; set; } + + public int? QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset OrderDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } +} diff --git a/src/Web/ViewModels/QuoteExcerptViewModel.cs b/src/Web/ViewModels/QuoteExcerptViewModel.cs new file mode 100644 index 0000000..20fdada --- /dev/null +++ b/src/Web/ViewModels/QuoteExcerptViewModel.cs @@ -0,0 +1,29 @@ +using System; + +namespace Nethereum.eShop.Web.ViewModels +{ + public class QuoteExcerptViewModel + { + public int QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset QuoteDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } +} diff --git a/src/Web/Views/Order/MyOrders.cshtml b/src/Web/Views/Order/MyOrders.cshtml index 7478ba6..9b94b71 100644 --- a/src/Web/Views/Order/MyOrders.cshtml +++ b/src/Web/Views/Order/MyOrders.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @{ ViewData["Title"] = "My Order History"; } @@ -7,7 +7,8 @@

@ViewData["Title"]

-
Order number
+
Id
+
PO
Date
Total
Status
@@ -17,21 +18,22 @@ { @foreach (var item in Model) { -
-
@Html.DisplayFor(modelItem => item.OrderNumber)
-
@Html.DisplayFor(modelItem => item.OrderDate)
-
$ @Html.DisplayFor(modelItem => item.Total)
-
@Html.DisplayFor(modelItem => item.Status)
-
- Detail -
-
- @if (item.Status.ToLower() == "submitted") - { - Cancel - } -
-
+
+
@Html.DisplayFor(modelItem => item.OrderId)
+
@Html.DisplayFor(modelItem => item.PoNumber)
+
@Html.DisplayFor(modelItem => item.OrderDate)
+
$ @Html.DisplayFor(modelItem => item.Total)
+
@Html.DisplayFor(modelItem => item.Status)
+
+ Detail +
+
+ @if (item.Status.ToLower() == "submitted") + { + Cancel + } +
+
} }
diff --git a/src/Web/Views/Quote/MyQuotes.cshtml b/src/Web/Views/Quote/MyQuotes.cshtml index a44a2bf..784cc65 100644 --- a/src/Web/Views/Quote/MyQuotes.cshtml +++ b/src/Web/Views/Quote/MyQuotes.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @{ ViewData["Title"] = "My Quotes"; } @@ -9,7 +9,8 @@
Id
Date
-
Total
+
PO
+
Total
Status
@@ -17,21 +18,22 @@ { @foreach (var item in Model) { -
-
@Html.DisplayFor(modelItem => item.QuoteId)
-
@Html.DisplayFor(modelItem => item.QuoteDate)
-
$ @Html.DisplayFor(modelItem => item.Total)
-
@Html.DisplayFor(modelItem => item.Status)
-
- Detail -
-
- @if (item.Status.ToLower() == "submitted") - { - Cancel - } -
-
+
+
@Html.DisplayFor(modelItem => item.QuoteId)
+
@Html.DisplayFor(modelItem => item.QuoteDate)
+
@Html.DisplayFor(modelItem => item.PoNumber)
+
$ @Html.DisplayFor(modelItem => item.Total)
+
@Html.DisplayFor(modelItem => item.Status)
+
+ Detail +
+
+ @if (item.Status.ToLower() == "submitted") + { + Cancel + } +
+
@if (item.TransactionHash?.Length > 0) { diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index eef855e..d71cdbc 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -13,30 +13,25 @@ + - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index 036551a..c12a92d 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -2,9 +2,20 @@ // In the development environments, connection strings and keys are normally loaded from user-secrets // Right click Project and "Manage User Secrets" "ConnectionStrings": { - "CatalogConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;" + "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "IdentityConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", + "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db", + "CatalogConnection_MySql": "server=localhost;database=eShop;user=user;password=password", + "IdentityConnection_MySql": "server=localhost;database=eShop;user=user;password=password" }, + // SqlServer, Sqlite, InMemory (default) + "CatalogDbProvider": "InMemory", + "AppIdentityDbProvider": "InMemory", + "CatalogApplyMigrationsOnStartup": true, + "IdentityApplyMigrationsOnStartup": true, + "EthereumRpcUrl": "http://localhost:8545/", + "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0", "CatalogSeedJsonFile": "../../resources/data/TopRankBooks/ImportData/TopRankBooksForCatalogImport.json", "CatalogBaseUrl": "", "BizEngineRetriesUponFailure": 3, diff --git a/src/WebJobs/Config/EshopConfiguration.cs b/src/WebJobs/Config/EshopConfiguration.cs deleted file mode 100644 index 1543e26..0000000 --- a/src/WebJobs/Config/EshopConfiguration.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Configuration; -using System.Numerics; -using Microsoft.Azure; -using Microsoft.WindowsAzure; - - -namespace Nethereum.eShop.WebJobs.Configuration -{ - - public class EshopConfiguration - { - public string EthereumRpcUrl { get; set; } - public string AccountPrivateKey { get; set; } - - public string SellerId { get; set; } - - public string BuyerWalletAddress { get; set; } - - public bool CreateFakePurchaseOrders { get; set; } - - public PurchaseOrderEventLogProcessingConfiguration PurchaseOrderEventLogConfiguration { get; set; } - } - - public class PurchaseOrderEventLogProcessingConfiguration - { - public bool Enabled { get; set; } = true; - - public string BlockProgressJsonFile { get; set; } - - public string MinimumStartingBlock { get; set; } = "0"; - - public uint NumberOfBlocksPerBatch { get; set; } = 10; - - public uint MinimumBlockConfirmations { get; set; } = 12; - - public BigInteger GetMinimumStartingBlock() => BigInteger.Parse(MinimumStartingBlock); - - public int TimeoutMs { get; set; } - } - -} \ No newline at end of file diff --git a/src/WebJobs/Functions.cs b/src/WebJobs/Functions.cs index 34c48ee..49212a1 100644 --- a/src/WebJobs/Functions.cs +++ b/src/WebJobs/Functions.cs @@ -33,7 +33,7 @@ public async Task CreateFakePurchaseOrders([TimerTrigger("00:00:05")] TimerInfo // the hack below works locally using the same app instance // but will most likely fail on Azure // where a new instance of the app will probably be instantiated on each interval - static bool _processing = false; + private static bool _processing = false; // [Singleton] public async Task ProcessBlockchainEvents([TimerTrigger("00:00:05")] TimerInfo timer, ILogger logger) diff --git a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs index d85d39f..eadc925 100644 --- a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs +++ b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs @@ -1,12 +1,12 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Nethereum.Commerce.Contracts; +using Nethereum.Commerce.Contracts.BuyerWallet; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; -using Nethereum.Commerce.Contracts.WalletBuyer; using Nethereum.Contracts; +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; -using Nethereum.eShop.WebJobs.Configuration; using Nethereum.Web3.Accounts; using System; using System.Collections.Generic; @@ -20,57 +20,58 @@ namespace Nethereum.eShop.WebJobs.Jobs { public class CreateFakePurchaseOrders : ICreateFakePurchaseOrders { - private readonly EshopConfiguration _config; + private readonly IConfiguration _configuration; + private readonly ISettingRepository _settingRepository; private readonly IQuoteRepository _quoteRepository; - public CreateFakePurchaseOrders(EshopConfiguration config, IQuoteRepository quoteRepository) + public CreateFakePurchaseOrders(IConfiguration configuration, ISettingRepository settingRepository, IQuoteRepository quoteRepository) { - this._config = config; + _configuration = configuration; + _settingRepository = settingRepository; this._quoteRepository = quoteRepository; } - public class GetQuotesRequiringPurchaseOrderSpec : BaseSpecification - { - public GetQuotesRequiringPurchaseOrderSpec() - : base(quote => quote.Status == QuoteStatus.Pending && quote.PoNumber == null) - { - AddInclude(b => b.QuoteItems); - } - } - public async Task ExecuteAsync(ILogger logger) { - if (!_config.CreateFakePurchaseOrders) return; + var dbBasedConfig = await _settingRepository.GetEShopConfigurationSettingsAsync().ConfigureAwait(false); + + if (!dbBasedConfig.CreateFakePurchaseOrdersJob.Enabled) return; - var pendingQuotes = await _quoteRepository.ListAsync(new GetQuotesRequiringPurchaseOrderSpec()); + var pendingQuotes = await _quoteRepository.GetQuotesRequiringPurchaseOrderAsync(); logger.LogInformation($"{pendingQuotes.Count} were found requiring a purchase order"); if (!pendingQuotes.Any()) return; - var account = new Account(_config.AccountPrivateKey); - var web3 = new Web3.Web3(account); - var walletBuyerService = new WalletBuyerService(web3, _config.BuyerWalletAddress); + var url = _configuration["EthereumRpcUrl"]; + var privateKey = _configuration["AccountPrivateKey"]; + + var web3 = new Web3.Web3(new Account(privateKey), url); + + var walletBuyerService = new BuyerWalletService(web3, dbBasedConfig.BuyerWalletAddress); foreach (var quote in pendingQuotes) { - await CreatePoForQuote(logger, walletBuyerService, quote); + await CreatePoForQuote(dbBasedConfig, web3, logger, walletBuyerService, quote); } } - private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuyerService, Quote quote) + private async Task CreatePoForQuote(EShopConfigurationSettings dbBasedConfig, Web3.Web3 web3, ILogger logger, BuyerWalletService walletBuyerService, Quote quote) { - var existing = await walletBuyerService.GetPoBySellerAndQuoteQueryAsync(_config.SellerId, quote.Id); + var existing = await walletBuyerService.GetPoByEshopIdAndQuoteQueryAsync(dbBasedConfig.EShop.Id, quote.Id); if (existing?.Po?.PoNumber > 0) { quote.PoNumber = (long)existing.Po.PoNumber; quote.Status = QuoteStatus.AwaitingOrder; - await _quoteRepository.UpdateAsync(quote); + _quoteRepository.Update(quote); + await _quoteRepository.UnitOfWork.SaveEntitiesAsync(); return; } - var po = CreateDummyPoForPurchasingCreate(quote).ToBuyerPo(); - var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(po); + var po = CreateDummyPoForPurchasingCreate(dbBasedConfig, web3, quote).ToBuyerPo(); + var signature = po.GetSignatureBytes(web3); + var poArgs = new Nethereum.Commerce.Contracts.BuyerWallet.ContractDefinition.CreatePurchaseOrderFunction { Po = po, Signature = signature }; + var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poArgs); var createdEvent = receipt.DecodeAllEvents().FirstOrDefault(); @@ -80,7 +81,8 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy quote.PoNumber = (long)createdEvent.Event.PoNumber; quote.Status = QuoteStatus.AwaitingOrder; quote.TransactionHash = receipt.TransactionHash; - await _quoteRepository.UpdateAsync(quote); + _quoteRepository.Update(quote); + await _quoteRepository.UnitOfWork.SaveEntitiesAsync(); } else { @@ -88,31 +90,44 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy } } - public Storage.Po CreateDummyPoForPurchasingCreate(Quote quote) + public Po CreateDummyPoForPurchasingCreate(EShopConfigurationSettings dbBasedConfig, Web3.Web3 web3, Quote quote) { - var po = new Storage.Po() + return CreatePoForPurchasingContracts( + buyerUserAddress: web3.TransactionManager.Account.Address.ToLowerInvariant(), + buyerReceiverAddress: web3.TransactionManager.Account.Address.ToLowerInvariant(), + buyerWalletAddress: dbBasedConfig.BuyerWalletAddress.ToLowerInvariant(), + eShopId: dbBasedConfig.EShop.Id, + sellerId: dbBasedConfig.Seller.Id, + currencySymbol: dbBasedConfig.CurrencySymbol, + currencyAddress: dbBasedConfig.CurrencyAddress.ToLowerInvariant(), + quote: quote, + isLargeValue: false); + } + + public Po CreatePoForPurchasingContracts( + string buyerUserAddress, + string buyerReceiverAddress, + string buyerWalletAddress, + string eShopId, + string sellerId, + string currencySymbol, + string currencyAddress, + Quote quote, + bool isLargeValue = false) + { + BigInteger valueLine01 = BigInteger.Parse("110000000000000000000"); // eg this is 110 dai + BigInteger valueLine02 = BigInteger.Parse("220000000000000000000"); // eg this is 220 dai + if (isLargeValue) { - // PoNumber assigned by contract - BuyerAddress = "0x37ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - ReceiverAddress = "0x36ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - BuyerWalletAddress = "0x39ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - CurrencySymbol = "DAI", - CurrencyAddress = "0x41ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - QuoteId = quote.Id, - QuoteExpiryDate = DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds(), - ApproverAddress = string.Empty, // assigned by contract - PoType = PoType.Cash, - SellerId = _config.SellerId, - // PoCreateDate assigned by contract - // PoItemCount assigned by contract - PoItems = new List() - }; + valueLine01 *= 1000; + valueLine02 *= 1000; + } - //gtin1111 + var items = new List(quote.ItemCount()); foreach (var quoteItem in quote.QuoteItems) { - po.PoItems.Add(new Storage.PoItem + items.Add(new Storage.PoItem { // PoNumber assigned by contract // PoItemNumber assigned by contract @@ -122,7 +137,8 @@ public Storage.Po CreateDummyPoForPurchasingCreate(Quote quote) Quantity = quoteItem.Quantity, Unit = "EA", QuantitySymbol = "NA", - QuantityAddress = "0x40ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", + // TODO: remove or replace Quantity Address + QuantityAddress = "0x40ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610".ToLowerInvariant(), CurrencyValue = quoteItem.CurrencyValue == null ? 0 : BigInteger.Parse(quoteItem.CurrencyValue), // Status assigned by contract // GoodsIssuedDate assigned by contract @@ -134,7 +150,38 @@ public Storage.Po CreateDummyPoForPurchasingCreate(Quote quote) }); } - return po; + var po = new Storage.Po() + { + // PoNumber assigned by contract + + BuyerUserAddress = buyerUserAddress, + BuyerReceiverAddress = buyerReceiverAddress, + BuyerWalletAddress = buyerWalletAddress, + + EShopId = eShopId, + QuoteId = quote.Id, + QuoteExpiryDate = new BigInteger(DateTimeOffset.Now.AddHours(1).ToUnixTimeSeconds()), + QuoteSignerAddress = string.Empty, // assigned by contract + + SellerId = sellerId, + + CurrencySymbol = currencySymbol, + CurrencyAddress = currencyAddress, + PoType = PoType.Cash, + // PoCreateDate assigned by contract + // PoItemCount assigned by contract + PoItems = items, + // RulesCount assigned by contract + Rules = new List() + { + "rule01".ConvertToBytes32(), + "rule02".ConvertToBytes32(), + "rule03".ConvertToBytes32() + } + }; + + return po.ToPurchasingPo(); + } } } diff --git a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs index fc4bf91..ddcd142 100644 --- a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs +++ b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs @@ -1,4 +1,5 @@ using Common.Logging; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Nethereum.BlockchainProcessing; using Nethereum.BlockchainProcessing.LogProcessing; @@ -6,10 +7,8 @@ using Nethereum.BlockchainProcessing.Processor; using Nethereum.BlockchainProcessing.ProgressRepositories; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; -using Nethereum.Commerce.Contracts.WalletBuyer; using Nethereum.eShop.ApplicationCore.Exceptions; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.WebJobs.Configuration; using Nethereum.Microsoft.Logging.Utils; using Nethereum.RPC.Eth.Blocks; using Nethereum.RPC.Eth.DTOs; @@ -21,26 +20,29 @@ namespace Nethereum.eShop.WebJobs.Jobs { public class ProcessPurchaseOrderEventLogs : IProcessPuchaseOrderEventLogs { - private readonly EshopConfiguration _eshopConfiguration; - private readonly PurchaseOrderEventLogProcessingConfiguration _config; + private readonly IConfiguration _configuration; + private readonly ISettingRepository _settingRepository; private readonly IOrderService _orderService; private readonly IBlockProgressRepository BlockProgressRepository = null; public ProcessPurchaseOrderEventLogs( - EshopConfiguration eshopConfiguration, + IConfiguration configuration, + ISettingRepository settingRepository, IOrderService orderService, IBlockProgressRepository blockProgressRepository ) { - _eshopConfiguration = eshopConfiguration; + _configuration = configuration; + _settingRepository = settingRepository; _orderService = orderService; - _config = eshopConfiguration.PurchaseOrderEventLogConfiguration; BlockProgressRepository = blockProgressRepository; } public async Task ExecuteAsync(ILogger logger) { - if (!_config.Enabled) + var dbConfigSettings = await _settingRepository.GetEShopConfigurationSettingsAsync(); + + if (!dbConfigSettings.ProcessPurchaseOrderEvents.Enabled) { logger.LogInformation($"{nameof(ProcessPurchaseOrderEventLogs)} is not enabled - see app settings"); return; @@ -48,11 +50,10 @@ public async Task ExecuteAsync(ILogger logger) const int RequestRetryWeight = 0; // see below for retry algorithm - var web3 = new Web3.Web3(_eshopConfiguration.EthereumRpcUrl); - var walletBuyerService = new WalletBuyerService(web3, _eshopConfiguration.BuyerWalletAddress); - var purchasingContractAddress = await walletBuyerService.PurchasingQueryAsync(); + var url = _configuration["EthereumRpcUrl"]; - var filter = new NewFilterInput { Address = new[] { purchasingContractAddress } }; + var web3 = new Web3.Web3(url); + var filter = new NewFilterInput { Address = new[] { dbConfigSettings.PurchasingContractAddress } }; ILog log = logger.ToILog(); @@ -66,7 +67,7 @@ public async Task ExecuteAsync(ILogger logger) ethApi: web3.Eth, logProcessors: logProcessorHandlers, filterInput: filter, - defaultNumberOfBlocksPerRequest: (int)_config.NumberOfBlocksPerBatch, + defaultNumberOfBlocksPerRequest: dbConfigSettings.ProcessPurchaseOrderEvents.NumberOfBlocksPerBatch, retryWeight: RequestRetryWeight); IWaitStrategy waitForBlockConfirmationsStrategy = new WaitStrategy(); @@ -75,18 +76,18 @@ public async Task ExecuteAsync(ILogger logger) new LastConfirmedBlockNumberService( web3.Eth.Blocks.GetBlockNumber, waitForBlockConfirmationsStrategy, - _config.MinimumBlockConfirmations, + (uint)dbConfigSettings.ProcessPurchaseOrderEvents.MinimumBlockConfirmations, log); var processor = new BlockchainProcessor( orchestrator, BlockProgressRepository, lastConfirmedBlockNumberService); - var cancellationToken = new CancellationTokenSource(_config.TimeoutMs); + var cancellationToken = new CancellationTokenSource(dbConfigSettings.ProcessPurchaseOrderEvents.TimeoutMs); var currentBlockOnChain = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync(); - var blockToProcessTo = currentBlockOnChain.Value - _config.MinimumBlockConfirmations; + var blockToProcessTo = currentBlockOnChain.Value - dbConfigSettings.ProcessPurchaseOrderEvents.MinimumBlockConfirmations; var lastBlockProcessed = await BlockProgressRepository.GetLastBlockNumberProcessedAsync(); - var minStartingBlock = _config.GetMinimumStartingBlock(); + var minStartingBlock = dbConfigSettings.ProcessPurchaseOrderEvents.MinimumStartingBlock; logger.LogInformation( $"Processing logs. To Block: {blockToProcessTo}, Last Block Processed: {lastBlockProcessed ?? 0}, Min Block: {minStartingBlock}"); diff --git a/src/WebJobs/JsonFileBlockProgressRepository.cs b/src/WebJobs/JsonFileBlockProgressRepository.cs index 3ce1615..43ad1c4 100644 --- a/src/WebJobs/JsonFileBlockProgressRepository.cs +++ b/src/WebJobs/JsonFileBlockProgressRepository.cs @@ -1,20 +1,51 @@ using Nethereum.BlockchainProcessing.ProgressRepositories; -using System; -using System.Collections.Generic; +using Nethereum.eShop.ApplicationCore.Interfaces; using System.IO; -using System.Text; +using System.Numerics; using System.Threading.Tasks; namespace Nethereum.eShop.WebJobs { - public class JsonFileBlockProgressRepository: JsonBlockProgressRepository + public class JsonFileBlockProgressRepository : IBlockProgressRepository { - public JsonFileBlockProgressRepository(string jsonFile):base( - () => Task.FromResult(File.Exists(jsonFile)), - async (json) => await File.WriteAllTextAsync(jsonFile, json), - async () => await File.ReadAllTextAsync(jsonFile)) + private readonly ISettingRepository _settingRepository; + private IBlockProgressRepository _innerRepo; + + public JsonFileBlockProgressRepository(ISettingRepository settingRepository) { + _settingRepository = settingRepository; + } + public async Task GetLastBlockNumberProcessedAsync() + { + await InitRepo(); + return await _innerRepo.GetLastBlockNumberProcessedAsync().ConfigureAwait(false); + } + public async Task UpsertProgressAsync(BigInteger blockNumber) + { + await InitRepo(); + await _innerRepo.UpsertProgressAsync(blockNumber).ConfigureAwait(false); + } + + private async Task InitRepo() + { + if (_innerRepo == null) + { + var config = await _settingRepository.GetEShopConfigurationSettingsAsync().ConfigureAwait(false); + _innerRepo = new PrivateJsonFileBlockProgressRepository(config.ProcessPurchaseOrderEvents.BlockProgressJsonFile); + } + } + + public class PrivateJsonFileBlockProgressRepository : JsonBlockProgressRepository + { + public PrivateJsonFileBlockProgressRepository(string jsonFile) : base( + () => Task.FromResult(File.Exists(jsonFile)), + async (json) => await File.WriteAllTextAsync(jsonFile, json), + async () => await File.ReadAllTextAsync(jsonFile)) + { + + } } } + } diff --git a/src/WebJobs/Program.cs b/src/WebJobs/Program.cs index 899883f..98c31d9 100644 --- a/src/WebJobs/Program.cs +++ b/src/WebJobs/Program.cs @@ -1,19 +1,13 @@ -using Microsoft.EntityFrameworkCore; +using MediatR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Nethereum.BlockchainProcessing.BlockStorage.Entities; using Nethereum.BlockchainProcessing.ProgressRepositories; -using Nethereum.BlockchainStore.EFCore; -using Nethereum.BlockchainStore.EFCore.Repositories; -using Nethereum.BlockchainStore.EFCore.SqlServer; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; -using Nethereum.eShop.Infrastructure.Data; -using Nethereum.eShop.WebJobs.Configuration; +using Nethereum.eShop.DbFactory; using Nethereum.eShop.WebJobs.Jobs; -using System; namespace Nethereum.eShop.WebJobs { @@ -21,41 +15,46 @@ class Program { static void Main(string[] args) { - IConfigurationRoot config = null; - EshopConfiguration eShopConfig = null; + IConfiguration config = null; var hostBuilder = Host.CreateDefaultBuilder(args); - hostBuilder.ConfigureServices(c => + hostBuilder.ConfigureServices(services => { - c.AddDbContext((serviceProvider, options) => - options.UseSqlServer(config.GetConnectionString("CatalogConnection"))); + // TODO: Configure MediatR properly - this is just a place holder + services.AddMediatR(typeof(Program)); - // config - c.AddSingleton(eShopConfig); + // db + var dbBootstrapper = EShopDbBootstrapper.CreateDbBootstrapper(config); + dbBootstrapper.AddDbContext(services, config); + + //repositories + dbBootstrapper.AddRepositories(services, config); // supporting services - c.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); - c.AddScoped(); - c.AddScoped(); - c.AddScoped(); + services.AddScoped(); + + // TODO: There's a bug in the BlockProgressRepo + // It's using string ordering instead of numeric ordering to get the last block processed + // so 997 is considered higher than 2061 + // this has been fixed but is awaiting a PR merge and nuget release (probably 3.7.2) // blockchain event log progress db - var progressDbConnectionString = config.GetConnectionString("BlockchainProcessingProgressDb"); - IBlockchainDbContextFactory blockchainDbContextFactory = - new SqlServerCoreBlockchainDbContextFactory( - progressDbConnectionString, DbSchemaNames.dbo); + //var progressDbConnectionString = config.GetConnectionString("BlockchainProcessingProgressDb"); + //IBlockchainDbContextFactory blockchainDbContextFactory = + // new SqlServerCoreBlockchainDbContextFactory( + // progressDbConnectionString, DbSchemaNames.dbo); - using (var progressContext = blockchainDbContextFactory.CreateContext()) - { - progressContext.Database.EnsureCreated(); - } + //using (var progressContext = blockchainDbContextFactory.CreateContext()) + //{ + // progressContext.Database.EnsureCreated(); + //} - IBlockProgressRepository progressRepo = new BlockProgressRepository(blockchainDbContextFactory); - c.AddSingleton(progressRepo); + //IBlockProgressRepository progressRepo = new BlockProgressRepository(blockchainDbContextFactory); + services.AddScoped(); // jobs - c.AddScoped(); - c.AddScoped(); + services.AddScoped(); + services.AddScoped(); }); hostBuilder.ConfigureWebJobs(b => @@ -71,7 +70,6 @@ static void Main(string[] args) c.AddUserSecrets(typeof(Program).Assembly); config = c.Build(); - eShopConfig = config.GetSection("EshopConfiguration").Get(); }); hostBuilder.ConfigureLogging((context, b) => @@ -87,5 +85,6 @@ static void Main(string[] args) } } } + } } diff --git a/src/WebJobs/WebJobs.csproj b/src/WebJobs/WebJobs.csproj index 372866b..9111e34 100644 --- a/src/WebJobs/WebJobs.csproj +++ b/src/WebJobs/WebJobs.csproj @@ -3,12 +3,15 @@ Exe netcoreapp3.1 - Nethereum.Shop.WebJobs Nethereum.eShop.WebJobs - + + + Nethereum.eShop.Web.UserSecrets + + @@ -17,12 +20,12 @@ - + diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index 906556c..0af2719 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -2,25 +2,13 @@ // In the development environments, connection strings and keys are normally loaded from user-secrets // Right click Project and "Manage User Secrets" "ConnectionStrings": { - "CatalogConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", "BlockchainProcessingProgressDb": "Server=localhost;Integrated Security=true;Initial Catalog=eShopWebJobs;" }, + // SqlServer, Sqlite, MySql (InMemory is no good for the WebJobs project as it needs to share the same DB as the main Web app) + "CatalogDbProvider": "SqlServer", "AzureWebJobsStorage": "", - "EshopConfiguration": { - "EthereumRpcUrl": "http://localhost:8545/", - "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0", - "SellerId": "Nethereum.eShop", - "BuyerWalletAddress": "0x969b34204c90947822e278d10482b79a51c1544f", - "CreateFakePurchaseOrders": true, - - "PurchaseOrderEventLogConfiguration": { - "Enabled": true, - "BlockProgressJsonFile": "c:/temp/po_blockprogress.json", - "MinimumStartingBlock": 3200, - "NumberOfBlocksPerBatch": 100, - "MinimumBlockConfirmations": 12, - "TimeoutMs": 3600000 - } - } + "EthereumRpcUrl": "http://localhost:8545/", + "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0" } \ No newline at end of file diff --git a/src/WebJobs/libman.json b/src/WebJobs/libman.json new file mode 100644 index 0000000..ceee271 --- /dev/null +++ b/src/WebJobs/libman.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "defaultProvider": "cdnjs", + "libraries": [] +} \ No newline at end of file diff --git a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs index 4465beb..b45a577 100644 --- a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs +++ b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs @@ -34,8 +34,8 @@ public class ContractDeploymentsFixture : IAsyncLifetime public ContractDeploymentsFixture(IMessageSink diagnosticMessageSink) { _diagnosticMessageSink = diagnosticMessageSink; - var appConfig = ConfigurationUtils.Build(Array.Empty(), "UserSecret"); - + var appConfig = ConfigurationUtils.Build(Array.Empty(), "Nethereum.Commerce.ContractDeployments.IntegrationTests"); + // Web3 var web3Config = appConfig.GetSection("Web3Config").Get(); var privateKey = web3Config.TransactionCreatorPrivateKey; diff --git a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj index d4a6150..dfbc7cc 100644 --- a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj +++ b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj @@ -4,6 +4,7 @@ netcoreapp3.1 false + Nethereum.Commerce.ContractDeployments.IntegrationTests diff --git a/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs b/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs index 773637a..fa4dcd0 100644 --- a/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs +++ b/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs @@ -22,6 +22,8 @@ using System; using System.Threading.Tasks; using System.Diagnostics; +using System.IO; +using Newtonsoft.Json; namespace Nethereum.Commerce.Contracts.Deployment { @@ -152,6 +154,7 @@ public async Task InitializeAsync() LogSeparator(); } + private async Task DeployAndConfigureEShopAsync() { try diff --git a/src/utils/Books.ImportUtil/Books.ImportUtil.csproj b/src/utils/Books.ImportUtil/Books.ImportUtil.csproj index 89d39c8..0a0d91f 100644 --- a/src/utils/Books.ImportUtil/Books.ImportUtil.csproj +++ b/src/utils/Books.ImportUtil/Books.ImportUtil.csproj @@ -18,6 +18,7 @@ + diff --git a/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs b/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs index ebcedf4..9f293e1 100644 --- a/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs +++ b/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs @@ -1,6 +1,5 @@ -using CsvHelper.Configuration; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.EntityFramework.Catalog.Seed; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -104,10 +103,10 @@ private static CatalogImportDto GenerateCatalogImport( Dictionary> bookCoverDictionary) { var excerpt = new CatalogImportDto(); - var bookCatalogType = new CatalogType { Id = 1, Type = "Book" }; + var bookCatalogType = new CatalogTypeForImport { Id = 1, Type = "Book" }; excerpt.CatalogTypes.Add(bookCatalogType); - var authorDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + var authorDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); int id = 0; int authorIdCounter = 0; @@ -125,19 +124,19 @@ private static CatalogImportDto GenerateCatalogImport( return excerpt; } - private static CatalogItem Convert( + private static CatalogItemForImport Convert( int catalogTypeIdForBooks, BookWithDescription book, Dictionary> bookCoverDictionary, int id, - Dictionary authorDictionary, + Dictionary authorDictionary, ref int authorIdCounter) { if (!authorDictionary.ContainsKey(book.Book.AUTHOR)) { authorIdCounter++; - authorDictionary[book.Book.AUTHOR] = new CatalogBrand + authorDictionary[book.Book.AUTHOR] = new CatalogBrandForImport { Id = authorIdCounter, Brand = book.Book.AUTHOR @@ -164,7 +163,7 @@ private static CatalogItem Convert( return Decimal.TryParse(i, out var d) ? (int)(d * 25.4m) : 0; }); - var catalogItem = new CatalogItem { + var catalogItem = new CatalogItemForImport { Id = id, Rank = id, Gtin = book.Book.EAN,