Skip to content

Commit

Permalink
Sm 104 project Database (#2192)
Browse files Browse the repository at this point in the history
* Project DB addition and sprocs

* Adding spaces to the end of each file, fixing minor issues

* removing useless comments

* Adding soft delete proc to migration

* Project EF Scaffold

* Additional changes to use EF instead of procedures

* Adding dependency injection

* Fixing lint errors

* Bug fixes

* Adding migration scripts, removing sproc files, and setting up Entity framework code

* Adding back accidentally deleted sproc

* Removing files that shouldn't have been created

* Lint

* Small changes based on Oscar's rec (#2215)

* Migrations for making CreateDate not null

* adding space to end of file

* Making Revision date not null

* dotnet format

* Adding nonclustered indexes to SQL

* SM-104: Update PR with changes Thomas proposed

Co-authored-by: CarleyDiaz-Bitwarden <103955722+CarleyDiaz-Bitwarden@users.noreply.github.com>
Co-authored-by: Thomas Avery <tavery@bitwarden.com>
Co-authored-by: Colton Hurst <colton@coltonhurst.com>
  • Loading branch information
4 people authored Sep 5, 2022
1 parent f3085f5 commit de08ad5
Show file tree
Hide file tree
Showing 17 changed files with 3,851 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public static class CommercialEFServiceCollectionExtensions
public static void AddCommercialEFRepositories(this IServiceCollection services)
{
services.AddSingleton<ISecretRepository, SecretRepository>();
services.AddSingleton<IProjectRepository, ProjectRepository>();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using AutoMapper;
using Bit.Core.Repositories;
using Bit.Infrastructure.EntityFramework.Models;
using Bit.Infrastructure.EntityFramework.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace Bit.Commercial.Infrastructure.EntityFramework.Repositories
{
public class ProjectRepository : Repository<Core.Entities.Project, Project, Guid>, IProjectRepository
{
public ProjectRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
: base(serviceScopeFactory, mapper, db => db.Project)
{

}

public override async Task<Core.Entities.Project> GetByIdAsync(Guid id)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var project = await dbContext.Project
.Where(c => c.Id == id && c.DeletedDate == null)
.FirstOrDefaultAsync();
return Mapper.Map<Core.Entities.Project>(project);
}
}

public async Task<IEnumerable<Core.Entities.Project>> GetManyByOrganizationIdAsync(Guid organizationId)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var project = await dbContext.Project
.Where(c => c.OrganizationId == organizationId && c.DeletedDate == null)
.OrderBy(c => c.RevisionDate)
.ToListAsync();
return Mapper.Map<List<Core.Entities.Project>>(project);
}
}

public async Task SoftDeleteManyByIdAsync(IEnumerable<Guid> ids)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var dbContext = GetDatabaseContext(scope);
var utcNow = DateTime.UtcNow;
var project = dbContext.Project.Where(c => ids.Contains(c.Id));
await project.ForEachAsync(project =>
{
dbContext.Attach(project);
project.DeletedDate = utcNow;
project.RevisionDate = utcNow;
});
await dbContext.SaveChangesAsync();
}
}
}
}
28 changes: 28 additions & 0 deletions src/Core/Entities/Project.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#nullable enable
using Bit.Core.Utilities;

namespace Bit.Core.Entities
{
public class Project : ITableObject<Guid>
{
public Guid Id { get; set; }

public Guid OrganizationId { get; set; }

public string? Name { get; set; }

public DateTime CreationDate { get; set; }

public DateTime RevisionDate { get; set; }

public DateTime? DeletedDate { get; set; }

public void SetNewId()
{
if (Id == default(Guid))
{
Id = CoreHelpers.GenerateComb();
}
}
}
}
13 changes: 13 additions & 0 deletions src/Core/Repositories/IProjectRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Bit.Core.Entities;

namespace Bit.Core.Repositories
{
public interface IProjectRepository
{
Task<IEnumerable<Project>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<Project> GetByIdAsync(Guid id);
Task<Project> CreateAsync(Project project);
Task ReplaceAsync(Project project);
Task SoftDeleteManyByIdAsync(IEnumerable<Guid> ids);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Bit.Infrastructure.EntityFramework.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class ProjectEntityTypeConfiguration : IEntityTypeConfiguration<Project>
{
public void Configure(EntityTypeBuilder<Project> builder)
{
builder
.Property(s => s.Id)
.ValueGeneratedNever();

builder
.HasKey(s => s.Id)
.IsClustered();

builder
.HasIndex(s => s.DeletedDate)
.IsClustered(false);

builder
.HasIndex(s => s.OrganizationId)
.IsClustered(false);

builder.ToTable(nameof(Project));
}
}
17 changes: 17 additions & 0 deletions src/Infrastructure.EntityFramework/Models/Project.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using AutoMapper;

namespace Bit.Infrastructure.EntityFramework.Models
{
public class Project : Core.Entities.Project
{
public virtual Organization Organization { get; set; }
}

public class ProjectMapperProfile : Profile
{
public ProjectMapperProfile()
{
CreateMap<Core.Entities.Project, Project>().ReverseMap();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public DatabaseContext(DbContextOptions<DatabaseContext> options)
public DbSet<Policy> Policies { get; set; }
public DbSet<Provider> Providers { get; set; }
public DbSet<Secret> Secret { get; set; }
public DbSet<Project> Project { get; set; }
public DbSet<ProviderUser> ProviderUsers { get; set; }
public DbSet<ProviderOrganization> ProviderOrganizations { get; set; }
public DbSet<Send> Sends { get; set; }
Expand Down
16 changes: 16 additions & 0 deletions src/Sql/dbo/Tables/Project.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CREATE TABLE [dbo].[Project] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[OrganizationId] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR(MAX) NULL,
[CreationDate] DATETIME2 (7),
[RevisionDate] DATETIME2 (7),
[DeletedDate] DATETIME2 (7) NULL,
CONSTRAINT [PK_Project] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Project_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [dbo].[Organization] ([Id]) ON DELETE CASCADE,
);

GO
CREATE NONCLUSTERED INDEX [IX_Project_OrganizationId] ON [dbo].[Project] ([OrganizationId] ASC);

GO
CREATE NONCLUSTERED INDEX [IX_Project_DeletedDate] ON [dbo].[Project] ([DeletedDate] ASC);
20 changes: 20 additions & 0 deletions util/Migrator/DbScripts/2022-08-10_00_Project.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
IF OBJECT_ID('[dbo].[Project]') IS NULL
BEGIN
CREATE TABLE [dbo].[Project] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[OrganizationId] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR(MAX) NULL,
[CreationDate] DATETIME2 (7),
[RevisionDate] DATETIME2 (7),
[DeletedDate] DATETIME2 (7) NULL,
CONSTRAINT [PK_Project] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Project_Organization] FOREIGN KEY ([OrganizationId]) REFERENCES [dbo].[Organization] ([Id]) ON DELETE CASCADE,
);

CREATE NONCLUSTERED INDEX [IX_Project_OrganizationId] ON [dbo].[Project] ([OrganizationId] ASC);

CREATE NONCLUSTERED INDEX [IX_Project_DeletedDate] ON [dbo].[Project] ([DeletedDate] ASC);

END

GO
Loading

0 comments on commit de08ad5

Please sign in to comment.