1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-10 20:07:56 +01:00

event sql table and repo

This commit is contained in:
Kyle Spearrin 2017-12-12 14:22:22 -05:00
parent 7b359053d6
commit ce1680a009
11 changed files with 225 additions and 19 deletions

View File

@ -3,7 +3,7 @@ using Bit.Core.Enums;
namespace Bit.Core.Models.Data
{
public class Event : IEvent
public class EventMessage : IEvent
{
public DateTime Date { get; set; }
public EventType Type { get; set; }

View File

@ -5,7 +5,6 @@ namespace Bit.Core.Models.Data
{
public interface IEvent
{
DateTime Date { get; set; }
EventType Type { get; set; }
Guid? UserId { get; set; }
Guid? OrganizationId { get; set; }
@ -14,5 +13,6 @@ namespace Bit.Core.Models.Data
Guid? GroupId { get; set; }
Guid? OrganizationUserId { get; set; }
Guid? ActingUserId { get; set; }
DateTime Date { get; set; }
}
}

View File

@ -0,0 +1,41 @@
using System;
using Bit.Core.Enums;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Table
{
public class Event : ITableObject<Guid>, IEvent
{
public Event() { }
public Event(IEvent e)
{
Date = e.Date;
Type = e.Type;
UserId = e.UserId;
OrganizationId = e.OrganizationId;
CipherId = e.CipherId;
CollectionId = e.CollectionId;
GroupId = e.GroupId;
OrganizationUserId = e.OrganizationUserId;
ActingUserId = e.ActingUserId;
}
public Guid Id { get; set; }
public DateTime Date { get; set; }
public EventType Type { get; set; }
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Guid? CipherId { get; set; }
public Guid? CollectionId { get; set; }
public Guid? GroupId { get; set; }
public Guid? OrganizationUserId { get; set; }
public Guid? ActingUserId { get; set; }
public void SetNewId()
{
Id = CoreHelpers.GenerateComb();
}
}
}

View File

@ -8,7 +8,7 @@ namespace Bit.Core.Repositories
public interface IEventRepository
{
Task<ICollection<IEvent>> GetManyByUserAsync(Guid userId, DateTime startDate, DateTime endDate);
Task CreateAsync(IEvent entity);
Task CreateManyAsync(IList<IEvent> entities);
Task CreateAsync(IEvent e);
Task CreateManyAsync(IList<IEvent> e);
}
}

View File

@ -392,8 +392,7 @@ namespace Bit.Core.Repositories.SqlServer
{
if(folders.Any())
{
using(var bulkCopy = new SqlBulkCopy(connection,
SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers, transaction))
using(var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
{
bulkCopy.DestinationTableName = "[dbo].[Folder]";
var dataTable = BuildFoldersTable(folders);
@ -401,8 +400,7 @@ namespace Bit.Core.Repositories.SqlServer
}
}
using(var bulkCopy = new SqlBulkCopy(connection,
SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers, transaction))
using(var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
{
bulkCopy.DestinationTableName = "[dbo].[Cipher]";
var dataTable = BuildCiphersTable(ciphers);

View File

@ -0,0 +1,115 @@
using System;
using Bit.Core.Models.Table;
using System.Threading.Tasks;
using System.Collections.Generic;
using Bit.Core.Models.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Data;
namespace Bit.Core.Repositories.SqlServer
{
public class EventRepository : Repository<Event, Guid>, IEventRepository
{
public EventRepository(GlobalSettings globalSettings)
: this(globalSettings.SqlServer.ConnectionString)
{ }
public EventRepository(string connectionString)
: base(connectionString)
{ }
public Task<ICollection<IEvent>> GetManyByUserAsync(Guid userId, DateTime startDate, DateTime endDate)
{
// TODO
throw new NotImplementedException();
}
public async Task CreateAsync(IEvent e)
{
if(!(e is Event ev))
{
ev = new Event(e);
}
await base.CreateAsync(ev);
}
public async Task CreateManyAsync(IList<IEvent> entities)
{
if(!entities.Any())
{
return;
}
using(var connection = new SqlConnection(ConnectionString))
{
connection.Open();
using(var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, null))
{
bulkCopy.DestinationTableName = "[dbo].[Event]";
var dataTable = BuildEventsTable(entities.Select(e => e is Event ? e as Event : new Event(e)));
await bulkCopy.WriteToServerAsync(dataTable);
}
}
}
private DataTable BuildEventsTable(IEnumerable<Event> events)
{
var e = events.FirstOrDefault();
if(e == null)
{
throw new ApplicationException("Must have some events to bulk import.");
}
var eventsTable = new DataTable("EventDataTable");
var idColumn = new DataColumn(nameof(e.Id), e.Id.GetType());
eventsTable.Columns.Add(idColumn);
var typeColumn = new DataColumn(nameof(e.Type), typeof(int));
eventsTable.Columns.Add(typeColumn);
var dateColumn = new DataColumn(nameof(e.Date), e.Date.GetType());
eventsTable.Columns.Add(dateColumn);
var userIdColumn = new DataColumn(nameof(e.UserId), typeof(Guid));
eventsTable.Columns.Add(userIdColumn);
var organizationIdColumn = new DataColumn(nameof(e.OrganizationId), typeof(Guid));
eventsTable.Columns.Add(organizationIdColumn);
var cipherIdColumn = new DataColumn(nameof(e.CipherId), typeof(Guid));
eventsTable.Columns.Add(cipherIdColumn);
var groupIdColumn = new DataColumn(nameof(e.GroupId), typeof(Guid));
eventsTable.Columns.Add(groupIdColumn);
var collectionIdColumn = new DataColumn(nameof(e.CollectionId), typeof(Guid));
eventsTable.Columns.Add(collectionIdColumn);
var actingUserIdColumn = new DataColumn(nameof(e.ActingUserId), typeof(Guid));
eventsTable.Columns.Add(actingUserIdColumn);
var organizationUserIdColumn = new DataColumn(nameof(e.OrganizationUserId), typeof(Guid));
eventsTable.Columns.Add(organizationUserIdColumn);
var keys = new DataColumn[1];
keys[0] = idColumn;
eventsTable.PrimaryKey = keys;
foreach(var ev in events)
{
ev.SetNewId();
var row = eventsTable.NewRow();
row[idColumn] = ev.Id;
row[typeColumn] = ev.Type;
row[dateColumn] = ev.Date;
row[userIdColumn] = ev.UserId;
row[organizationIdColumn] = ev.OrganizationId;
row[cipherIdColumn] = ev.CipherId;
row[groupIdColumn] = ev.GroupId;
row[collectionIdColumn] = ev.CollectionId;
row[actingUserIdColumn] = ev.ActingUserId;
row[organizationUserIdColumn] = ev.OrganizationUserId;
eventsTable.Rows.Add(row);
}
return eventsTable;
}
}
}

View File

@ -33,7 +33,7 @@ namespace Bit.Core.Services
var now = DateTime.UtcNow;
var events = new List<IEvent>
{
new Event
new EventMessage
{
UserId = userId,
Type = type,
@ -44,7 +44,7 @@ namespace Bit.Core.Services
IEnumerable<IEvent> orgEvents;
if(_currentContext.UserId.HasValue)
{
orgEvents = _currentContext.Organizations.Select(o => new Event
orgEvents = _currentContext.Organizations.Select(o => new EventMessage
{
OrganizationId = o.Id,
UserId = userId,
@ -56,7 +56,7 @@ namespace Bit.Core.Services
{
var orgs = await _organizationUserRepository.GetManyByUserAsync(userId);
orgEvents = orgs.Where(o => o.Status == OrganizationUserStatusType.Confirmed)
.Select(o => new Event
.Select(o => new EventMessage
{
OrganizationId = o.Id,
UserId = userId,
@ -83,7 +83,7 @@ namespace Bit.Core.Services
return;
}
var e = new Event
var e = new EventMessage
{
OrganizationId = cipher.OrganizationId,
UserId = cipher.OrganizationId.HasValue ? null : cipher.UserId,
@ -97,7 +97,7 @@ namespace Bit.Core.Services
public async Task LogCollectionEventAsync(Collection collection, EventType type)
{
var e = new Event
var e = new EventMessage
{
OrganizationId = collection.OrganizationId,
CollectionId = collection.Id,
@ -110,7 +110,7 @@ namespace Bit.Core.Services
public async Task LogGroupEventAsync(Group group, EventType type)
{
var e = new Event
var e = new EventMessage
{
OrganizationId = group.OrganizationId,
GroupId = group.Id,
@ -123,7 +123,7 @@ namespace Bit.Core.Services
public async Task LogOrganizationUserEventAsync(OrganizationUser organizationUser, EventType type)
{
var e = new Event
var e = new EventMessage
{
OrganizationId = organizationUser.OrganizationId,
UserId = organizationUser.UserId,
@ -137,7 +137,7 @@ namespace Bit.Core.Services
public async Task LogOrganizationEventAsync(Organization organization, EventType type)
{
var e = new Event
var e = new EventMessage
{
OrganizationId = organization.Id,
Type = type,

View File

@ -44,7 +44,7 @@ namespace Bit.Core.Utilities
if(globalSettings.SelfHosted)
{
// TODO: Sql server event repo
services.AddSingleton<IEventRepository, SqlServerRepos.EventRepository>();
}
else
{

View File

@ -42,13 +42,13 @@ namespace Bit.EventsProcessor
var token = JToken.Parse(message);
if(token is JArray)
{
var events = token.ToObject<List<Event>>()
var events = token.ToObject<List<EventMessage>>()
.Select(e => new EventTableEntity(e) as IEvent).ToList();
await _eventWriteService.CreateManyAsync(events);
}
else if(token is JObject)
{
var e = token.ToObject<Event>();
var e = token.ToObject<EventMessage>();
await _eventWriteService.CreateAsync(new EventTableEntity(e));
}
}

View File

@ -0,0 +1,39 @@
CREATE PROCEDURE [dbo].[Event_Create]
@Id UNIQUEIDENTIFIER,
@Type INT,
@UserId UNIQUEIDENTIFIER,
@OrganizationId UNIQUEIDENTIFIER,
@CipherId UNIQUEIDENTIFIER,
@CollectionId UNIQUEIDENTIFIER,
@GroupId UNIQUEIDENTIFIER,
@OrganizationUserId UNIQUEIDENTIFIER,
@Date DATETIME2(7)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO [dbo].[Event]
(
[Id],
[Type],
[UserId],
[OrganizationId],
[CipherId],
[CollectionId],
[GroupId],
[OrganizationUserId],
[Date]
)
VALUES
(
@Id,
@Type,
@UserId,
@OrganizationId,
@CipherId,
@CollectionId,
@GroupId,
@OrganizationUserId,
@Date
)
END

View File

@ -0,0 +1,13 @@
CREATE TABLE [dbo].[Event] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[Type] INT NOT NULL,
[UserId] UNIQUEIDENTIFIER NULL,
[OrganizationId] UNIQUEIDENTIFIER NULL,
[CipherId] UNIQUEIDENTIFIER NULL,
[CollectionId] UNIQUEIDENTIFIER NULL,
[GroupId] UNIQUEIDENTIFIER NULL,
[OrganizationUserId] UNIQUEIDENTIFIER NULL,
[Date] DATETIME2 (7) NOT NULL,
CONSTRAINT [PK_Event] PRIMARY KEY CLUSTERED ([Id] ASC)
);