1
0
mirror of https://github.com/bitwarden/server synced 2026-01-05 18:13:31 +00:00

refactored cipherfolder and fav to JSON columns

This commit is contained in:
Kyle Spearrin
2017-04-15 22:26:45 -04:00
parent 8e193dfc62
commit f21652b46b
21 changed files with 216 additions and 272 deletions

View File

@@ -2,39 +2,158 @@
@Id UNIQUEIDENTIFIER,
@UserId UNIQUEIDENTIFIER,
@FolderId UNIQUEIDENTIFIER,
@Favorite TINYINT
@Favorite BIT
AS
BEGIN
SET NOCOUNT ON
DECLARE @FavoritesJson VARCHAR(MAX) = NULL
DECLARE @FoldersJson VARCHAR(MAX) = NULL
SELECT
@FavoritesJson = [Favorites],
@FoldersJson = [Folders]
FROM
[dbo].[Cipher]
WHERE
[Id] = @Id
DECLARE @ExistingFolderId UNIQUEIDENTIFIER = NULL
SELECT TOP 1
@ExistingFolderId = F.Id
FROM
[dbo].[FolderCipher] FC
INNER JOIN
[dbo].[Folder] F ON F.[Id] = FC.[FolderId]
WHERE
F.[UserId] = @UserId
AND FC.[CipherId] = @Id
-- NOTE
-- JSON_MODIFY operations involving @Existing__Index may be subject to race conditions involving that index/key.
-- Look for a better approach, like removing objects by conditions.
DECLARE @ExistingFolderIndex INT = NULL
DECLARE @ExistingFavoriteIndex INT = NULL
IF @ExistingFolderId IS NOT NULL AND (@FolderId IS NULL OR @FolderId != @ExistingFolderId)
IF @FoldersJson IS NOT NULL
BEGIN
EXEC [dbo].[FolderCipher_Delete] @ExistingFolderId, @Id
END
IF @FolderId IS NOT NULL AND (@ExistingFolderId IS NULL OR @FolderId != @ExistingFolderId)
BEGIN
EXEC [dbo].[FolderCipher_Create] @FolderId, @Id, @UserId
SELECT TOP 1
@ExistingFolderId = JSON_VALUE([Value], '$.f'),
@ExistingFolderIndex = [Key]
FROM (
SELECT
[Key],
[Value]
FROM
OPENJSON(@FoldersJson)
) [Results]
WHERE JSON_VALUE([Value], '$.u') = @UserId
END
IF @Favorite = 0
IF @FavoritesJson IS NOT NULL
BEGIN
EXEC [dbo].[Favorite_Delete] @UserId, @Id
SELECT TOP 1
@ExistingFavoriteIndex = [Key]
FROM (
SELECT
[Key],
[Value]
FROM
OPENJSON(@FavoritesJson)
) [Results]
WHERE JSON_VALUE([Value], '$.u') = @UserId
END
ELSE IF (SELECT COUNT(1) FROM [dbo].[Favorite] WHERE [UserId] = @UserId AND [CipherId] = @Id) = 0
-- ----------------------------
-- Update [Folders]
-- ----------------------------
IF @ExistingFolderId IS NOT NULL AND @FolderId IS NULL
BEGIN
EXEC [dbo].[Favorite_Create] @UserId, @Id
-- User had an existing folder, but now they have removed the folder assignment.
-- Remove the index of the existing folder object from the [Folders] JSON array.
UPDATE
[dbo].[Cipher]
SET
-- TODO: How to remove index?
[Folders] = JSON_MODIFY([Folders], CONCAT('$[', @ExistingFolderIndex, ']'), NULL)
WHERE
[Id] = @Id
END
ELSE IF @FolderId IS NOT NULL
BEGIN
IF @FoldersJson IS NULL
BEGIN
-- [Folders] has no existing JSON data.
-- Set @FolderId (with @UserId) as a new JSON object for index 0 of an array.
UPDATE
[dbo].[Cipher]
SET
[Folders] = JSON_QUERY((SELECT @UserId u, @FolderId f FOR JSON PATH))
WHERE
[Id] = @Id
END
ELSE IF @ExistingFolderId IS NULL
BEGIN
-- [Folders] has some existing JSON data, but the user had no existing folder.
-- Append @FolderId (with @UserId) as a new JSON object.
UPDATE
[dbo].[Cipher]
SET
[Folders] = JSON_MODIFY([Folders], 'append $',
JSON_QUERY((SELECT @UserId u, @FolderId f FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)))
WHERE
[Id] = @Id
END
ELSE IF @FolderId != @ExistingFolderId
BEGIN
-- User had an existing folder assignemnt, but have changed the assignment to another folder.
-- Update the index of the existing folder object from the [Folders] JSON array to to include the new @FolderId
UPDATE
[dbo].[Cipher]
SET
[Folders] = JSON_MODIFY([Folders], CONCAT('$[', @ExistingFolderIndex, ']'),
JSON_QUERY((SELECT @UserId u, @FolderId f FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)))
WHERE
[Id] = @Id
END
END
-- ----------------------------
-- Update [Favorites]
-- ----------------------------
IF @Favorite = 0 AND @ExistingFavoriteIndex IS NOT NULL
BEGIN
-- User had the cipher marked as a favorite, but now it is not.
-- Remove the index of the existing user object from the [Favorites] JSON array.
UPDATE
[dbo].[Cipher]
SET
-- TODO: How to remove index?
[Favorites] = JSON_MODIFY([Favorites], CONCAT('$[', @ExistingFavoriteIndex, ']'), NULL)
WHERE
[Id] = @Id
END
ELSE IF @Favorite = 1 AND @FavoritesJson IS NULL
BEGIN
-- User is marking the cipher as a favorite and there is no existing JSON data
-- Set @UserId as a new JSON object for index 0 of an array.
UPDATE
[dbo].[Cipher]
SET
[Favorites] = JSON_QUERY((SELECT @UserId u FOR JSON PATH))
WHERE
[Id] = @Id
END
ELSE IF @Favorite = 1 AND @ExistingFavoriteIndex IS NULL
BEGIN
-- User is marking the cipher as a favorite whenever it previously was not.
-- Append @UserId as a new JSON object.
UPDATE
[dbo].[Cipher]
SET
[Favorites] = JSON_MODIFY([Favorites], 'append $',
JSON_QUERY((SELECT @UserId u FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)))
WHERE
[Id] = @Id
END
END