diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0ca40408b70e04dc3284756a5caf9ae348d1526b..49a1dddfdeb57fb2338b2f141b5c0ed4bbaf7236 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,21 +22,25 @@ migrate: - dotnet tool install dotnet-ef; echo "1" - dotnet tool update dotnet-ef # Create new database and migrate to latest state - - dotnet build src\Database.Actions - - .\src\Database.Actions\bin\Debug\net5.0\Coscine.Database.Actions.exe --action-create --name $DB_NAME --source $DB_DATA_SOURCE --user $DB_USER_ID --pw $DB_PASSWORD + - dotnet run -p .\src\Database.Actions -- --action-create --name $DB_NAME --source $DB_DATA_SOURCE --user $DB_USER_ID --pw $DB_PASSWORD # Scaffold created database - - dotnet ef dbcontext scaffold "Data Source=$DB_DATA_SOURCE;Integrated Security=False;User ID=$DB_USER_ID;Password=$DB_PASSWORD;Database=$DB_NAME" Microsoft.EntityFrameworkCore.SqlServer -o DataModel -c "Model" -f --no-onconfiguring --project "src\Database" + - dotnet ef dbcontext scaffold "Data Source=$DB_DATA_SOURCE;Integrated Security=False;User ID=$DB_USER_ID;Password=$DB_PASSWORD;Database=$DB_NAME" Microsoft.EntityFrameworkCore.SqlServer -o DataModel -c "Model" -f --no-onconfiguring --project "src\Scaffolding" # Remove the hardcoded Connection String inside \DataModel\Model.cs - - Set-Content -Path ".\src\Database\DataModel\Model.txt" -Value (Get-Content -Path ".\src\Database\DataModel\Model.cs" | where { $_ | Select-String -Pattern '#warning' -NotMatch } | where { $_ | Select-String -Pattern 'Data Source=' -NotMatch } ) -Force - - Set-Content -Path ".\src\Database\DataModel\Model.cs" -Value (Get-Content -Path ".\src\Database\DataModel\Model.txt") -Force - - Remove-Item ".\src\Database\DataModel\Model.txt" + - Set-Content -Path ".\src\Scaffolding\DataModel\Model.txt" -Value (Get-Content -Path ".\src\Scaffolding\DataModel\Model.cs" | where { $_ | Select-String -Pattern '#warning' -NotMatch } | where { $_ | Select-String -Pattern 'Data Source=' -NotMatch } ) -Force + - Set-Content -Path ".\src\Scaffolding\DataModel\Model.cs" -Value (Get-Content -Path ".\src\Scaffolding\DataModel\Model.txt") -Force + - Remove-Item ".\src\Scaffolding\DataModel\Model.txt" + artifacts: + paths: + - src\Scaffolding\DataModel + expire_in: 1 week + cleanup: stage: cleanup extends: .dotnet-windows-base script: # Drop created database - - .\dist\Database.Actions\Coscine.Database.Actions.exe --action-drop --name $DB_NAME --source $DB_DATA_SOURCE --user $DB_USER_ID --pw $DB_PASSWORD + - dotnet run -p .\src\Database.Actions -- --action-drop --name $DB_NAME --source $DB_DATA_SOURCE --user $DB_USER_ID --pw $DB_PASSWORD when: always build-branch: diff --git a/src/Database.Tests/Database.Tests.csproj b/src/Database.Tests/Database.Tests.csproj index 791358757fca72d26e64a9c839466f7c0bfe42ba..dd24ad53d2c2e117b5f38058489ec78c9ad60538 100644 --- a/src/Database.Tests/Database.Tests.csproj +++ b/src/Database.Tests/Database.Tests.csproj @@ -14,7 +14,7 @@ <PackageReference Include="Coscine.Database.Helpers" Version="2.*-*" /> <PackageReference Include="Coscine.Migrations" Version="2.*-*" /> <PackageReference Include="linq2db" Version="3.2.3" /> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" /> <PackageReference Include="NUnit" Version="3.13.1" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> </ItemGroup> diff --git a/src/Database.sln b/src/Database.sln index 8873848345dc4c6de76486c167f126a46b5945f6..e1098e790d337c619f4ab06d2ceaf0319300a4b5 100644 --- a/src/Database.sln +++ b/src/Database.sln @@ -7,7 +7,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Database", "Database\Databa EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Database.Tests", "Database.Tests\Database.Tests.csproj", "{2A5D0EC8-E487-4B43-A311-05852464ED01}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Database.Actions", "Database.Actions\Database.Actions.csproj", "{CEFF114C-1102-43F5-9CD3-3352F18D67A4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Database.Actions", "Database.Actions\Database.Actions.csproj", "{CEFF114C-1102-43F5-9CD3-3352F18D67A4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scaffolding", "Scaffolding\Scaffolding.csproj", "{A2A4CB04-C609-49EB-9795-829A6210711D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,6 +29,10 @@ Global {CEFF114C-1102-43F5-9CD3-3352F18D67A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {CEFF114C-1102-43F5-9CD3-3352F18D67A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {CEFF114C-1102-43F5-9CD3-3352F18D67A4}.Release|Any CPU.Build.0 = Release|Any CPU + {A2A4CB04-C609-49EB-9795-829A6210711D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2A4CB04-C609-49EB-9795-829A6210711D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2A4CB04-C609-49EB-9795-829A6210711D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2A4CB04-C609-49EB-9795-829A6210711D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Database/Database.csproj b/src/Database/Database.csproj index a9e8bea91a53b7461ed37baa5d746e1906b54a7f..dadf15e84377f2cace6fbef1aad252d645d2d5d0 100644 --- a/src/Database/Database.csproj +++ b/src/Database/Database.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Library</OutputType> <RootNamespace>Coscine.Database</RootNamespace> @@ -23,6 +23,11 @@ <None Include="Coscine.Database.Key.snk" /> <Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net461'" /> </ItemGroup> + <ItemGroup> + <Compile Include="..\Scaffolding\DataModel\*.*"> + <Link>DataModel\%(Filename)%(Extension)</Link> + </Compile> + </ItemGroup> <ItemGroup> <PackageReference Include="Coscine.Configuration" Version="2.*-*" /> <PackageReference Include="LinqKit" Version="1.1.23" /> diff --git a/src/Scaffolding/CustomDesignTimeService.cs b/src/Scaffolding/CustomDesignTimeService.cs new file mode 100644 index 0000000000000000000000000000000000000000..1bd05650b496aa3f716531fc80761551429c6ec0 --- /dev/null +++ b/src/Scaffolding/CustomDesignTimeService.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.DependencyInjection; + +namespace Coscine.Database +{ + public class CustomDesignTimeService : IDesignTimeServices + { + public void ConfigureDesignTimeServices(IServiceCollection serviceCollection) + => serviceCollection.AddSingleton<IPluralizer, CustomPluralizer>(); + } + + public class CustomPluralizer : IPluralizer + { + Inflector.Inflector _inflector = new Inflector.Inflector(System.Globalization.CultureInfo.GetCultureInfo("en-us")); + + public string Pluralize(string identifier) + { + return _inflector.Pluralize(identifier) ?? identifier; + } + + public string Singularize(string identifier) + { + return _inflector.Singularize(identifier) ?? identifier; + } + } +} diff --git a/src/Database/DataModel/ActivatedFeature.cs b/src/Scaffolding/DataModel/ActivatedFeature.cs similarity index 100% rename from src/Database/DataModel/ActivatedFeature.cs rename to src/Scaffolding/DataModel/ActivatedFeature.cs diff --git a/src/Database/DataModel/ApiToken.cs b/src/Scaffolding/DataModel/ApiToken.cs similarity index 100% rename from src/Database/DataModel/ApiToken.cs rename to src/Scaffolding/DataModel/ApiToken.cs diff --git a/src/Database/DataModel/ContactChange.cs b/src/Scaffolding/DataModel/ContactChange.cs similarity index 100% rename from src/Database/DataModel/ContactChange.cs rename to src/Scaffolding/DataModel/ContactChange.cs diff --git a/src/Database/DataModel/Discipline.cs b/src/Scaffolding/DataModel/Discipline.cs similarity index 100% rename from src/Database/DataModel/Discipline.cs rename to src/Scaffolding/DataModel/Discipline.cs diff --git a/src/Database/DataModel/ExternalAuthenticator.cs b/src/Scaffolding/DataModel/ExternalAuthenticator.cs similarity index 100% rename from src/Database/DataModel/ExternalAuthenticator.cs rename to src/Scaffolding/DataModel/ExternalAuthenticator.cs diff --git a/src/Database/DataModel/ExternalId.cs b/src/Scaffolding/DataModel/ExternalId.cs similarity index 100% rename from src/Database/DataModel/ExternalId.cs rename to src/Scaffolding/DataModel/ExternalId.cs diff --git a/src/Database/DataModel/Feature.cs b/src/Scaffolding/DataModel/Feature.cs similarity index 100% rename from src/Database/DataModel/Feature.cs rename to src/Scaffolding/DataModel/Feature.cs diff --git a/src/Database/DataModel/GitlabResourceType.cs b/src/Scaffolding/DataModel/GitlabResourceType.cs similarity index 100% rename from src/Database/DataModel/GitlabResourceType.cs rename to src/Scaffolding/DataModel/GitlabResourceType.cs diff --git a/src/Database/DataModel/Group.cs b/src/Scaffolding/DataModel/Group.cs similarity index 100% rename from src/Database/DataModel/Group.cs rename to src/Scaffolding/DataModel/Group.cs diff --git a/src/Database/DataModel/GroupMembership.cs b/src/Scaffolding/DataModel/GroupMembership.cs similarity index 100% rename from src/Database/DataModel/GroupMembership.cs rename to src/Scaffolding/DataModel/GroupMembership.cs diff --git a/src/Database/DataModel/Kpi.cs b/src/Scaffolding/DataModel/Kpi.cs similarity index 100% rename from src/Database/DataModel/Kpi.cs rename to src/Scaffolding/DataModel/Kpi.cs diff --git a/src/Database/DataModel/Language.cs b/src/Scaffolding/DataModel/Language.cs similarity index 100% rename from src/Database/DataModel/Language.cs rename to src/Scaffolding/DataModel/Language.cs diff --git a/src/Database/DataModel/License.cs b/src/Scaffolding/DataModel/License.cs similarity index 100% rename from src/Database/DataModel/License.cs rename to src/Scaffolding/DataModel/License.cs diff --git a/src/Database/DataModel/LinkedResourceType.cs b/src/Scaffolding/DataModel/LinkedResourceType.cs similarity index 100% rename from src/Database/DataModel/LinkedResourceType.cs rename to src/Scaffolding/DataModel/LinkedResourceType.cs diff --git a/src/Database/DataModel/Log.cs b/src/Scaffolding/DataModel/Log.cs similarity index 100% rename from src/Database/DataModel/Log.cs rename to src/Scaffolding/DataModel/Log.cs diff --git a/src/Database/DataModel/Model.cs b/src/Scaffolding/DataModel/Model.cs similarity index 95% rename from src/Database/DataModel/Model.cs rename to src/Scaffolding/DataModel/Model.cs index 4745489d36ef647cdef333f627cfe95d8d776538..bdec87e1a54da96e0ea6d974f6a39dee45e1fd5e 100644 --- a/src/Database/DataModel/Model.cs +++ b/src/Scaffolding/DataModel/Model.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; @@ -21,6 +21,7 @@ namespace Coscine.Database.DataModel public virtual DbSet<ActivatedFeature> ActivatedFeatures { get; set; } public virtual DbSet<ApiToken> ApiTokens { get; set; } + public virtual DbSet<ContactChange> ContactChanges { get; set; } public virtual DbSet<Discipline> Disciplines { get; set; } public virtual DbSet<ExternalAuthenticator> ExternalAuthenticators { get; set; } public virtual DbSet<ExternalId> ExternalIds { get; set; } @@ -57,6 +58,8 @@ namespace Coscine.Database.DataModel { if (!optionsBuilder.IsConfigured) { +#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + optionsBuilder.UseSqlServer("Data Source=d-db-d02\\mssql14;Integrated Security=False;User ID=coscineDev;Password=Dev#123;Database=Coscine_hp-admin "); } } @@ -98,6 +101,29 @@ namespace Coscine.Database.DataModel .HasConstraintName("FK_ApiTokens_UserId_Users_Id"); }); + modelBuilder.Entity<ContactChange>(entity => + { + entity.HasKey(e => e.RelationId); + + entity.ToTable("ContactChange"); + + entity.Property(e => e.RelationId).HasDefaultValueSql("(newid())"); + + entity.Property(e => e.ConfirmationToken).HasDefaultValueSql("(newid())"); + + entity.Property(e => e.EditDate).HasColumnType("datetime"); + + entity.Property(e => e.NewEmail) + .IsRequired() + .HasMaxLength(200); + + entity.HasOne(d => d.User) + .WithMany(p => p.ContactChanges) + .HasForeignKey(d => d.UserId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_ContactChange_UserId_Users_Id"); + }); + modelBuilder.Entity<Discipline>(entity => { entity.Property(e => e.Id).HasDefaultValueSql("(newid())"); diff --git a/src/Database/DataModel/Project.cs b/src/Scaffolding/DataModel/Project.cs similarity index 100% rename from src/Database/DataModel/Project.cs rename to src/Scaffolding/DataModel/Project.cs diff --git a/src/Database/DataModel/ProjectDiscipline.cs b/src/Scaffolding/DataModel/ProjectDiscipline.cs similarity index 100% rename from src/Database/DataModel/ProjectDiscipline.cs rename to src/Scaffolding/DataModel/ProjectDiscipline.cs diff --git a/src/Database/DataModel/ProjectInstitute.cs b/src/Scaffolding/DataModel/ProjectInstitute.cs similarity index 100% rename from src/Database/DataModel/ProjectInstitute.cs rename to src/Scaffolding/DataModel/ProjectInstitute.cs diff --git a/src/Database/DataModel/ProjectQuota.cs b/src/Scaffolding/DataModel/ProjectQuota.cs similarity index 100% rename from src/Database/DataModel/ProjectQuota.cs rename to src/Scaffolding/DataModel/ProjectQuota.cs diff --git a/src/Database/DataModel/ProjectResource.cs b/src/Scaffolding/DataModel/ProjectResource.cs similarity index 100% rename from src/Database/DataModel/ProjectResource.cs rename to src/Scaffolding/DataModel/ProjectResource.cs diff --git a/src/Database/DataModel/ProjectRole.cs b/src/Scaffolding/DataModel/ProjectRole.cs similarity index 100% rename from src/Database/DataModel/ProjectRole.cs rename to src/Scaffolding/DataModel/ProjectRole.cs diff --git a/src/Database/DataModel/RdsresourceType.cs b/src/Scaffolding/DataModel/RdsresourceType.cs similarity index 100% rename from src/Database/DataModel/RdsresourceType.cs rename to src/Scaffolding/DataModel/RdsresourceType.cs diff --git a/src/Database/DataModel/Resource.cs b/src/Scaffolding/DataModel/Resource.cs similarity index 100% rename from src/Database/DataModel/Resource.cs rename to src/Scaffolding/DataModel/Resource.cs diff --git a/src/Database/DataModel/ResourceDiscipline.cs b/src/Scaffolding/DataModel/ResourceDiscipline.cs similarity index 100% rename from src/Database/DataModel/ResourceDiscipline.cs rename to src/Scaffolding/DataModel/ResourceDiscipline.cs diff --git a/src/Database/DataModel/ResourceType.cs b/src/Scaffolding/DataModel/ResourceType.cs similarity index 100% rename from src/Database/DataModel/ResourceType.cs rename to src/Scaffolding/DataModel/ResourceType.cs diff --git a/src/Database/DataModel/Role.cs b/src/Scaffolding/DataModel/Role.cs similarity index 100% rename from src/Database/DataModel/Role.cs rename to src/Scaffolding/DataModel/Role.cs diff --git a/src/Database/DataModel/S3resourceType.cs b/src/Scaffolding/DataModel/S3resourceType.cs similarity index 100% rename from src/Database/DataModel/S3resourceType.cs rename to src/Scaffolding/DataModel/S3resourceType.cs diff --git a/src/Database/DataModel/SubProject.cs b/src/Scaffolding/DataModel/SubProject.cs similarity index 100% rename from src/Database/DataModel/SubProject.cs rename to src/Scaffolding/DataModel/SubProject.cs diff --git a/src/Database/DataModel/Title.cs b/src/Scaffolding/DataModel/Title.cs similarity index 100% rename from src/Database/DataModel/Title.cs rename to src/Scaffolding/DataModel/Title.cs diff --git a/src/Database/DataModel/Tosaccepted.cs b/src/Scaffolding/DataModel/Tosaccepted.cs similarity index 100% rename from src/Database/DataModel/Tosaccepted.cs rename to src/Scaffolding/DataModel/Tosaccepted.cs diff --git a/src/Database/DataModel/User.cs b/src/Scaffolding/DataModel/User.cs similarity index 92% rename from src/Database/DataModel/User.cs rename to src/Scaffolding/DataModel/User.cs index 693b6adb7e504ace2f69e8cc474f81018fdf936a..e293e6d29548c737fecf2923f5f62bb5ed7e82e4 100644 --- a/src/Database/DataModel/User.cs +++ b/src/Scaffolding/DataModel/User.cs @@ -12,6 +12,7 @@ namespace Coscine.Database.DataModel public User() { ApiTokens = new HashSet<ApiToken>(); + ContactChanges = new HashSet<ContactChange>(); ExternalIds = new HashSet<ExternalId>(); GroupMemberships = new HashSet<GroupMembership>(); ProjectRoles = new HashSet<ProjectRole>(); @@ -33,6 +34,7 @@ namespace Coscine.Database.DataModel public virtual Language Language { get; set; } public virtual Title Title { get; set; } public virtual ICollection<ApiToken> ApiTokens { get; set; } + public virtual ICollection<ContactChange> ContactChanges { get; set; } public virtual ICollection<ExternalId> ExternalIds { get; set; } public virtual ICollection<GroupMembership> GroupMemberships { get; set; } public virtual ICollection<ProjectRole> ProjectRoles { get; set; } diff --git a/src/Database/DataModel/UserDiscipline.cs b/src/Scaffolding/DataModel/UserDiscipline.cs similarity index 100% rename from src/Database/DataModel/UserDiscipline.cs rename to src/Scaffolding/DataModel/UserDiscipline.cs diff --git a/src/Database/DataModel/VersionInfo.cs b/src/Scaffolding/DataModel/VersionInfo.cs similarity index 100% rename from src/Database/DataModel/VersionInfo.cs rename to src/Scaffolding/DataModel/VersionInfo.cs diff --git a/src/Database/DataModel/Visibility.cs b/src/Scaffolding/DataModel/Visibility.cs similarity index 100% rename from src/Database/DataModel/Visibility.cs rename to src/Scaffolding/DataModel/Visibility.cs diff --git a/src/Scaffolding/Scaffolding.csproj b/src/Scaffolding/Scaffolding.csproj new file mode 100644 index 0000000000000000000000000000000000000000..5e72e7205290832bc15595e65312ccdc44917688 --- /dev/null +++ b/src/Scaffolding/Scaffolding.csproj @@ -0,0 +1,12 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <RootNamespace>Coscine.Database</RootNamespace> + <TargetFrameworks>net5.0;net461</TargetFrameworks> + </PropertyGroup> + <ItemGroup> + <PackageReference Include="Inflector.NetStandard" Version="1.2.2" /> + <!-- Note: use Microsoft.EntityFrameworkCore Version 3.x.x for compatibility with net461 --> + <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.12" PrivateAssets="all" /> + <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.12" /> + </ItemGroup> +</Project>