diff --git a/src/Core/Models/Table/Cipher.cs b/src/Core/Models/Table/Cipher.cs index 94d386afeb..868cd1a413 100644 --- a/src/Core/Models/Table/Cipher.cs +++ b/src/Core/Models/Table/Cipher.cs @@ -10,6 +10,8 @@ namespace Bit.Core.Models.Table public Guid? OrganizationId { get; set; } public Enums.CipherType Type { get; set; } public string Data { get; set; } + public string Favorites { get; set; } + public string Folders { get; set; } public DateTime CreationDate { get; internal set; } = DateTime.UtcNow; public DateTime RevisionDate { get; internal set; } = DateTime.UtcNow; diff --git a/src/Core/Models/Table/Favorite.cs b/src/Core/Models/Table/Favorite.cs deleted file mode 100644 index a238b2b8d4..0000000000 --- a/src/Core/Models/Table/Favorite.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Bit.Core.Models.Table -{ - public class Favorite - { - public Guid CipherId { get; set; } - public Guid UserId { get; set; } - } -} diff --git a/src/Core/Models/Table/FolderCipher.cs b/src/Core/Models/Table/FolderCipher.cs deleted file mode 100644 index 19ac18db8f..0000000000 --- a/src/Core/Models/Table/FolderCipher.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Bit.Core.Models.Table -{ - public class FolderCipher - { - public Guid CipherId { get; set; } - public Guid FolderId { get; set; } - public Guid UserId { get; set; } - } -} diff --git a/src/Core/Repositories/ICipherRepository.cs b/src/Core/Repositories/ICipherRepository.cs index ba483599cb..4652167610 100644 --- a/src/Core/Repositories/ICipherRepository.cs +++ b/src/Core/Repositories/ICipherRepository.cs @@ -19,7 +19,6 @@ namespace Bit.Core.Repositories Task ReplaceAsync(Cipher obj, IEnumerable subvaultIds); Task UpdatePartialAsync(Guid id, Guid userId, Guid? folderId, bool favorite); Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable ciphers); - Task CreateAsync(IEnumerable ciphers, IEnumerable favorites, IEnumerable folders, - IEnumerable folderCiphers); + Task CreateAsync(IEnumerable ciphers, IEnumerable folders); } } diff --git a/src/Core/Repositories/SqlServer/CipherRepository.cs b/src/Core/Repositories/SqlServer/CipherRepository.cs index c7219f4e33..e22d4089c8 100644 --- a/src/Core/Repositories/SqlServer/CipherRepository.cs +++ b/src/Core/Repositories/SqlServer/CipherRepository.cs @@ -237,8 +237,7 @@ namespace Bit.Core.Repositories.SqlServer return Task.FromResult(0); } - public Task CreateAsync(IEnumerable ciphers, IEnumerable favorites, IEnumerable folders, - IEnumerable folderCiphers) + public Task CreateAsync(IEnumerable ciphers, IEnumerable folders) { if(!ciphers.Any()) { @@ -272,28 +271,6 @@ namespace Bit.Core.Repositories.SqlServer bulkCopy.WriteToServer(dataTable); } - if(folderCiphers.Any()) - { - using(var bulkCopy = new SqlBulkCopy(connection, - SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers, transaction)) - { - bulkCopy.DestinationTableName = "[dbo].[FolderCipher]"; - var dataTable = BuildFolderCiphersTable(folderCiphers); - bulkCopy.WriteToServer(dataTable); - } - } - - if(favorites.Any()) - { - using(var bulkCopy = new SqlBulkCopy(connection, - SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers, transaction)) - { - bulkCopy.DestinationTableName = "[dbo].[Favorite]"; - var dataTable = BuildFavoritesTable(favorites); - bulkCopy.WriteToServer(dataTable); - } - } - transaction.Commit(); } catch @@ -327,6 +304,10 @@ namespace Bit.Core.Repositories.SqlServer ciphersTable.Columns.Add(typeColumn); var dataColumn = new DataColumn(nameof(c.Data), typeof(string)); ciphersTable.Columns.Add(dataColumn); + var favoritesColumn = new DataColumn(nameof(c.Favorites), typeof(string)); + ciphersTable.Columns.Add(favoritesColumn); + var foldersColumn = new DataColumn(nameof(c.Folders), typeof(string)); + ciphersTable.Columns.Add(foldersColumn); var creationDateColumn = new DataColumn(nameof(c.CreationDate), c.CreationDate.GetType()); ciphersTable.Columns.Add(creationDateColumn); var revisionDateColumn = new DataColumn(nameof(c.RevisionDate), c.RevisionDate.GetType()); @@ -345,6 +326,8 @@ namespace Bit.Core.Repositories.SqlServer row[organizationId] = cipher.OrganizationId.HasValue ? (object)cipher.OrganizationId.Value : DBNull.Value; row[typeColumn] = (short)cipher.Type; row[dataColumn] = cipher.Data; + row[favoritesColumn] = cipher.Favorites; + row[foldersColumn] = cipher.Folders; row[creationDateColumn] = cipher.CreationDate; row[revisionDateColumn] = cipher.RevisionDate; @@ -354,76 +337,6 @@ namespace Bit.Core.Repositories.SqlServer return ciphersTable; } - private DataTable BuildFavoritesTable(IEnumerable favorites) - { - var f = favorites.FirstOrDefault(); - if(f == null) - { - throw new ApplicationException("Must have some favorites to bulk import."); - } - - var favoritesTable = new DataTable("FavoriteDataTable"); - - var userIdColumn = new DataColumn(nameof(f.UserId), f.UserId.GetType()); - favoritesTable.Columns.Add(userIdColumn); - var cipherIdColumn = new DataColumn(nameof(f.CipherId), f.CipherId.GetType()); - favoritesTable.Columns.Add(cipherIdColumn); - - var keys = new DataColumn[2]; - keys[0] = userIdColumn; - keys[1] = cipherIdColumn; - favoritesTable.PrimaryKey = keys; - - foreach(var favorite in favorites) - { - var row = favoritesTable.NewRow(); - - row[cipherIdColumn] = favorite.CipherId; - row[userIdColumn] = favorite.UserId; - - favoritesTable.Rows.Add(row); - } - - return favoritesTable; - } - - private DataTable BuildFolderCiphersTable(IEnumerable folderCiphers) - { - var f = folderCiphers.FirstOrDefault(); - if(f == null) - { - throw new ApplicationException("Must have some folderCiphers to bulk import."); - } - - var folderCiphersTable = new DataTable("FolderCipherDataTable"); - - var folderIdColumn = new DataColumn(nameof(f.FolderId), f.FolderId.GetType()); - folderCiphersTable.Columns.Add(folderIdColumn); - var cipherIdColumn = new DataColumn(nameof(f.CipherId), f.CipherId.GetType()); - folderCiphersTable.Columns.Add(cipherIdColumn); - var userIdColumn = new DataColumn(nameof(f.UserId), f.UserId.GetType()); - folderCiphersTable.Columns.Add(userIdColumn); - - var keys = new DataColumn[3]; - keys[0] = folderIdColumn; - keys[1] = cipherIdColumn; - keys[2] = userIdColumn; - folderCiphersTable.PrimaryKey = keys; - - foreach(var folderCipher in folderCiphers) - { - var row = folderCiphersTable.NewRow(); - - row[folderIdColumn] = folderCipher.FolderId; - row[cipherIdColumn] = folderCipher.CipherId; - row[userIdColumn] = folderCipher.UserId; - - folderCiphersTable.Rows.Add(row); - } - - return folderCiphersTable; - } - private DataTable BuildFoldersTable(IEnumerable folders) { var f = folders.FirstOrDefault(); diff --git a/src/Core/Services/Implementations/CipherService.cs b/src/Core/Services/Implementations/CipherService.cs index e843fa9e04..037813d08a 100644 --- a/src/Core/Services/Implementations/CipherService.cs +++ b/src/Core/Services/Implementations/CipherService.cs @@ -186,19 +186,13 @@ namespace Bit.Core.Services List ciphers, IEnumerable> folderRelationships) { - // Init. ids and build out favorites. - var favorites = new List(); foreach(var cipher in ciphers) { cipher.SetNewId(); if(cipher.UserId.HasValue && cipher.Favorite) { - favorites.Add(new Favorite - { - UserId = cipher.UserId.Value, - CipherId = cipher.Id - }); + cipher.Favorites = $"[{{\"u\":\"{cipher.UserId.ToString().ToUpperInvariant()}\"}}]"; } } @@ -209,7 +203,6 @@ namespace Bit.Core.Services } // Create the folder associations based on the newly created folder ids - var folderCiphers = new List(); foreach(var relationship in folderRelationships) { var cipher = ciphers.ElementAtOrDefault(relationship.Key); @@ -220,16 +213,12 @@ namespace Bit.Core.Services continue; } - folderCiphers.Add(new FolderCipher - { - FolderId = folder.Id, - CipherId = cipher.Id, - UserId = folder.UserId - }); + cipher.Folders = $"[{{\"u\":\"{cipher.UserId.ToString().ToUpperInvariant()}\"," + + $"\"f\":\"{folder.Id.ToString().ToUpperInvariant()}\"}}]"; } // Create it all - await _cipherRepository.CreateAsync(ciphers, favorites, folders, folderCiphers); + await _cipherRepository.CreateAsync(ciphers, folders); // push var userId = folders.FirstOrDefault()?.UserId ?? ciphers.FirstOrDefault()?.UserId; diff --git a/src/Sql/Sql.sqlproj b/src/Sql/Sql.sqlproj index cc074a1910..33560ade9a 100644 --- a/src/Sql/Sql.sqlproj +++ b/src/Sql/Sql.sqlproj @@ -70,9 +70,7 @@ - - @@ -104,10 +102,8 @@ - - @@ -115,9 +111,7 @@ - - diff --git a/src/Sql/dbo/Functions/CipherDetails.sql b/src/Sql/dbo/Functions/CipherDetails.sql index f26a6462f2..333efaf9fe 100644 --- a/src/Sql/dbo/Functions/CipherDetails.sql +++ b/src/Sql/dbo/Functions/CipherDetails.sql @@ -2,14 +2,44 @@ RETURNS TABLE AS RETURN SELECT - C.*, - CASE WHEN F.[CipherId] IS NULL THEN 0 ELSE 1 END [Favorite], - FO.[Id] [FolderId] + C.[Id], + C.[UserId], + C.[OrganizationId], + C.[Type], + C.[Data], + C.[CreationDate], + C.[RevisionDate], + CASE WHEN + C.[Favorites] IS NULL + OR ( + SELECT TOP 1 + 1 + FROM + OPENJSON(C.[Favorites]) + WITH ( + [Favorites_UserId] UNIQUEIDENTIFIER '$.u' + ) + WHERE + [Favorites_UserId] = @UserId + ) IS NULL + THEN 0 + ELSE 1 + END [Favorite], + CASE WHEN + C.[Folders] IS NULL + THEN NULL + ELSE ( + SELECT TOP 1 + [Folders_FolderId] + FROM + OPENJSON(C.[Folders]) + WITH ( + [Folders_UserId] UNIQUEIDENTIFIER '$.u', + [Folders_FolderId] UNIQUEIDENTIFIER '$.f' + ) + WHERE + [Folders_UserId] = @UserId + ) + END [FolderId] FROM [dbo].[Cipher] C -LEFT JOIN - [dbo].[Favorite] F ON F.[CipherId] = C.[Id] AND F.[UserId] = @UserId -LEFT JOIN - [dbo].[FolderCipher] FC ON FC.[UserId] = @UserId AND FC.[CipherId] = C.[Id] -LEFT JOIN - [dbo].[Folder] FO ON FO.[Id] = FC.[FolderId] \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/CipherDetails_Create.sql b/src/Sql/dbo/Stored Procedures/CipherDetails_Create.sql index 3d6bd84623..fdbc69da99 100644 --- a/src/Sql/dbo/Stored Procedures/CipherDetails_Create.sql +++ b/src/Sql/dbo/Stored Procedures/CipherDetails_Create.sql @@ -4,6 +4,8 @@ @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), + @Favorites NVARCHAR(MAX), -- not used + @Folders NVARCHAR(MAX), -- not used @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @FolderId UNIQUEIDENTIFIER, @@ -19,6 +21,8 @@ BEGIN [OrganizationId], [Type], [Data], + [Favorites], + [Folders], [CreationDate], [RevisionDate] ) @@ -29,17 +33,9 @@ BEGIN @OrganizationId, @Type, @Data, + CASE WHEN @Favorite = 0 THEN NULL ELSE JSON_QUERY((SELECT @UserId u FOR JSON PATH)) END, + CASE WHEN @FolderId IS NULL THEN NULL ELSE JSON_QUERY((SELECT @UserId u, @FolderId f FOR JSON PATH)) END, @CreationDate, @RevisionDate ) - - IF @FolderId IS NOT NULL - BEGIN - EXEC [dbo].[FolderCipher_Create] @FolderId, @Id, @UserId - END - - IF @Favorite = 1 - BEGIN - EXEC [dbo].[Favorite_Create] @UserId, @Id - END END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/CipherDetails_Update.sql b/src/Sql/dbo/Stored Procedures/CipherDetails_Update.sql index 6fc46d9fe7..1f5f6d046a 100644 --- a/src/Sql/dbo/Stored Procedures/CipherDetails_Update.sql +++ b/src/Sql/dbo/Stored Procedures/CipherDetails_Update.sql @@ -4,6 +4,8 @@ @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), + @Favorites NVARCHAR(MAX), -- not used + @Folders NVARCHAR(MAX), -- not used @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @FolderId UNIQUEIDENTIFIER, diff --git a/src/Sql/dbo/Stored Procedures/Cipher_Create.sql b/src/Sql/dbo/Stored Procedures/Cipher_Create.sql index dc3fe7693b..eebd99b861 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_Create.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_Create.sql @@ -4,6 +4,8 @@ @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), + @Favorites NVARCHAR(MAX), + @Folders NVARCHAR(MAX), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7) AS @@ -17,6 +19,8 @@ BEGIN [OrganizationId], [Type], [Data], + [Favorites], + [Folders], [CreationDate], [RevisionDate] ) @@ -27,6 +31,8 @@ BEGIN @OrganizationId, @Type, @Data, + @Favorites, + @Folders, @CreationDate, @RevisionDate ) diff --git a/src/Sql/dbo/Stored Procedures/Cipher_Update.sql b/src/Sql/dbo/Stored Procedures/Cipher_Update.sql index 8c05b46a3d..7378753397 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_Update.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_Update.sql @@ -4,6 +4,8 @@ @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), + @Favorites NVARCHAR(MAX), + @Folders NVARCHAR(MAX), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7) AS @@ -17,6 +19,8 @@ BEGIN [OrganizationId] = @OrganizationId, [Type] = @Type, [Data] = @Data, + [Favorites] = @Favorites, + [Folders] = @Folders, [CreationDate] = @CreationDate, [RevisionDate] = @RevisionDate WHERE diff --git a/src/Sql/dbo/Stored Procedures/Cipher_UpdatePartial.sql b/src/Sql/dbo/Stored Procedures/Cipher_UpdatePartial.sql index 04cbdd16b2..c414e84f4b 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_UpdatePartial.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_UpdatePartial.sql @@ -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 \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithSubvaults.sql b/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithSubvaults.sql index 6662e53960..0257a34972 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithSubvaults.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithSubvaults.sql @@ -4,6 +4,8 @@ @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), + @Favorites NVARCHAR(MAX), + @Folders NVARCHAR(MAX), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @SubvaultIds AS [dbo].[GuidIdArray] READONLY @@ -16,10 +18,9 @@ BEGIN SET [UserId] = NULL, [OrganizationId] = @OrganizationId, - [Type] = @Type, [Data] = @Data, - [CreationDate] = @CreationDate, [RevisionDate] = @RevisionDate + -- No need to update CreationDate, Favorites, Folders, or Type since that data will not change WHERE [Id] = @Id diff --git a/src/Sql/dbo/Stored Procedures/Favorite_Create.sql b/src/Sql/dbo/Stored Procedures/Favorite_Create.sql deleted file mode 100644 index 932c9c6e0b..0000000000 --- a/src/Sql/dbo/Stored Procedures/Favorite_Create.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE PROCEDURE [dbo].[Favorite_Create] - @UserId UNIQUEIDENTIFIER, - @CipherId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - INSERT INTO [dbo].[Favorite] - ( - [UserId], - [CipherId] - ) - VALUES - ( - @UserId, - @CipherId - ) -END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/Favorite_Delete.sql b/src/Sql/dbo/Stored Procedures/Favorite_Delete.sql deleted file mode 100644 index acc38fe7fb..0000000000 --- a/src/Sql/dbo/Stored Procedures/Favorite_Delete.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE PROCEDURE [dbo].[Favorite_Delete] - @UserId UNIQUEIDENTIFIER, - @CipherId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - DELETE - FROM - [dbo].[Favorite] - WHERE - [UserId] = @UserId - AND [CipherId] = @CipherId -END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/FolderCipher_Create.sql b/src/Sql/dbo/Stored Procedures/FolderCipher_Create.sql deleted file mode 100644 index 94035d4c09..0000000000 --- a/src/Sql/dbo/Stored Procedures/FolderCipher_Create.sql +++ /dev/null @@ -1,21 +0,0 @@ -CREATE PROCEDURE [dbo].[FolderCipher_Create] - @FolderId UNIQUEIDENTIFIER, - @CipherId UNIQUEIDENTIFIER, - @UserId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - INSERT INTO [dbo].[FolderCipher] - ( - [FolderId], - [CipherId], - [UserId] - ) - VALUES - ( - @FolderId, - @CipherId, - @UserId - ) -END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/FolderCipher_Delete.sql b/src/Sql/dbo/Stored Procedures/FolderCipher_Delete.sql deleted file mode 100644 index 5bf2334204..0000000000 --- a/src/Sql/dbo/Stored Procedures/FolderCipher_Delete.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE PROCEDURE [dbo].[FolderCipher_Delete] - @FolderId UNIQUEIDENTIFIER, - @CipherId UNIQUEIDENTIFIER, - @UserId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - DELETE - FROM - [dbo].[FolderCipher] - WHERE - [FolderId] = @FolderId - AND [CipherId] = @CipherId - AND [UserId] = @UserId -END \ No newline at end of file diff --git a/src/Sql/dbo/Tables/Cipher.sql b/src/Sql/dbo/Tables/Cipher.sql index 7a59d4c897..8605e8c3ff 100644 --- a/src/Sql/dbo/Tables/Cipher.sql +++ b/src/Sql/dbo/Tables/Cipher.sql @@ -4,6 +4,8 @@ [OrganizationId] UNIQUEIDENTIFIER NULL, [Type] TINYINT NOT NULL, [Data] NVARCHAR (MAX) NOT NULL, + [Favorites] NVARCHAR (MAX) NULL, + [Folders] NVARCHAR (MAX) NULL, [CreationDate] DATETIME2 (7) NOT NULL, [RevisionDate] DATETIME2 (7) NOT NULL, CONSTRAINT [PK_Cipher] PRIMARY KEY CLUSTERED ([Id] ASC), diff --git a/src/Sql/dbo/Tables/Favorite.sql b/src/Sql/dbo/Tables/Favorite.sql deleted file mode 100644 index 8f9d19415c..0000000000 --- a/src/Sql/dbo/Tables/Favorite.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE [dbo].[Favorite] ( - [UserId] UNIQUEIDENTIFIER NOT NULL, - [CipherId] UNIQUEIDENTIFIER NOT NULL, - CONSTRAINT [PK_Favorite] PRIMARY KEY CLUSTERED ([UserId] ASC, [CipherId] ASC), - CONSTRAINT [FK_Favorite_Cipher] FOREIGN KEY ([CipherId]) REFERENCES [dbo].[Cipher] ([Id]) ON DELETE CASCADE, - CONSTRAINT [FK_Favorite_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) -); - diff --git a/src/Sql/dbo/Tables/FolderCipher.sql b/src/Sql/dbo/Tables/FolderCipher.sql deleted file mode 100644 index bceab2f3e3..0000000000 --- a/src/Sql/dbo/Tables/FolderCipher.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE [dbo].[FolderCipher] ( - [FolderId] UNIQUEIDENTIFIER NOT NULL, - [CipherId] UNIQUEIDENTIFIER NOT NULL, - [UserId] UNIQUEIDENTIFIER NOT NULL, - CONSTRAINT [PK_FolderCipher] PRIMARY KEY CLUSTERED ([UserId] ASC, [FolderId] ASC, [CipherId] ASC), - CONSTRAINT [FK_FolderCipher_Cipher] FOREIGN KEY ([CipherId]) REFERENCES [dbo].[Cipher] ([Id]) ON DELETE CASCADE, - CONSTRAINT [FK_FolderCipher_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) ON DELETE CASCADE, - CONSTRAINT [FK_FolderCipher_Folder] FOREIGN KEY ([FolderId]) REFERENCES [dbo].[Folder] ([Id]) -); - - -GO -CREATE NONCLUSTERED INDEX [IX_FolderCipher_CipherId] - ON [dbo].[FolderCipher]([CipherId] ASC); -