Last active
May 8, 2024 18:59
-
-
Save AlbertoDePena/fa60922ed539ad81947be4c6145b30eb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
USE EventStore; | |
GO | |
CREATE TABLE dbo.Events | |
( | |
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, | |
[Type] NVARCHAR(256) NOT NULL, | |
[Data] NVARCHAR(MAX) NOT NULL, | |
[Version] INT NOT NULL, | |
[StreamName] NVARCHAR(256) NOT NULL, | |
[Timestamp] DATETIMEOFFSET(7) NOT NULL DEFAULT SYSDATETIMEOFFSET(), | |
UNIQUE ([StreamName], [Version]), | |
CHECK ([Version] > 0) | |
); | |
GO | |
CREATE NONCLUSTERED INDEX IX_Events_StreamName ON [Events] ([StreamName]); | |
GO | |
CREATE TYPE NewEvent AS TABLE | |
( | |
[Id] UNIQUEIDENTIFIER NOT NULL, | |
[Type] [NVARCHAR](256) NOT NULL, | |
[Data] [NVARCHAR](MAX) NOT NULL | |
); | |
GO | |
CREATE TABLE [Snapshots] | |
( | |
[Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, | |
[Description] [NVARCHAR](1024) NOT NULL, | |
[Data] [NVARCHAR](MAX) NOT NULL, | |
[Version] [INT] NOT NULL, | |
[Timestamp] [DATETIMEOFFSET](7) NOT NULL DEFAULT SYSDATETIMEOFFSET(), | |
[StreamName] NVARCHAR(256) NOT NULL, | |
UNIQUE ([StreamName], [Version]), | |
CHECK ([Version] > 0) | |
); | |
GO | |
CREATE PROCEDURE dbo.GetStreams | |
@StreamName NVARCHAR(256) = NULL, | |
@Page INT = 1, | |
@PageSize INT = 25 | |
AS | |
SELECT | |
[StreamName], | |
MAX([Version]) AS [Version], | |
MAX([Timestamp]) AS [Timestamp] | |
FROM [dbo].[Events] | |
WHERE (@StreamName IS NULL OR [StreamName] = @StreamName) | |
GROUP BY [StreamName] | |
ORDER BY [StreamName] | |
OFFSET (@Page - 1) * @PageSize ROWS | |
FETCH NEXT @PageSize ROWS ONLY | |
OPTION | |
(RECOMPILE); | |
SELECT COUNT(DISTINCT [StreamName]) AS [TotalCount] | |
FROM [dbo].[Events] | |
WHERE (@StreamName IS NULL OR [StreamName] = @StreamName) | |
OPTION | |
(RECOMPILE); | |
GO | |
CREATE PROCEDURE [dbo].[GetStream] | |
@StreamName NVARCHAR(256) | |
AS | |
BEGIN | |
SELECT | |
[StreamName], | |
MAX([Version]) AS [Version], | |
MAX([Timestamp]) AS [Timestamp] | |
FROM [dbo].[Events] | |
WHERE [StreamName] = @StreamName | |
GROUP BY [StreamName]; | |
END | |
GO | |
CREATE PROCEDURE [dbo].[GetEvents] | |
@StreamName NVARCHAR(256), | |
@StartAtVersion [INT] = 0 | |
AS | |
BEGIN | |
SELECT | |
[Id], | |
[StreamName], | |
[Type], | |
[Data], | |
[Version], | |
[Timestamp] | |
FROM [dbo].[Events] | |
WHERE [StreamName] = @StreamName | |
AND [Version] >= @StartAtVersion | |
ORDER BY [Version]; | |
END | |
GO | |
CREATE PROCEDURE dbo.SaveEvents | |
@StreamName NVARCHAR(256), | |
@StreamVersion INT, | |
@NewEvents NewEvent READONLY | |
AS | |
BEGIN | |
BEGIN TRANSACTION | |
DECLARE @ExpectedVersion INT; | |
BEGIN TRY | |
SELECT @ExpectedVersion = COALESCE(MAX([Version]), 0) | |
FROM [dbo].[Events] | |
WHERE [StreamName] = @StreamName; | |
IF @ExpectedVersion <> @StreamVersion | |
BEGIN | |
DECLARE @ErrorMessage NVARCHAR(256) = CONCAT('Concurrency violation: expected stream version to be ', CAST(@ExpectedVersion AS VARCHAR(256))); | |
;THROW 50001, @ErrorMessage, 1; | |
END | |
INSERT INTO [dbo].[Events] | |
( | |
[Id], | |
[StreamName], | |
[Type], | |
[Data], | |
[Version] | |
) | |
SELECT | |
[Id], | |
@StreamName, | |
[Type], | |
[Data], | |
(row_number() over (order by (select NULL)) + @ExpectedVersion) | |
FROM @NewEvents; | |
COMMIT TRANSACTION | |
END TRY | |
BEGIN CATCH | |
IF @@TRANCOUNT > 0 | |
BEGIN | |
ROLLBACK TRANSACTION; | |
END; | |
THROW; | |
END CATCH | |
END | |
GO |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment