From ecb9f4581de69e7eaf8a2ef6b89aaeff60e99f53 Mon Sep 17 00:00:00 2001 From: Artemy <109195690+stalcker2288969@users.noreply.github.com> Date: Sun, 1 Mar 2026 19:17:54 +0700 Subject: [PATCH] fix searching of push tokens --- .../UserPushTokenConfiguration.cs | 21 +- ...0301120522_FixPushTokensIndexs.Designer.cs | 838 ++++++++++++++++++ .../20260301120522_FixPushTokensIndexs.cs | 82 ++ .../Migrations/GovorDbContextModelSnapshot.cs | 12 +- .../Repositories/PushTokenRepository.cs | 4 +- 5 files changed, 946 insertions(+), 11 deletions(-) create mode 100644 Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.Designer.cs create mode 100644 Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.cs diff --git a/Govor.Data/Configurations/UserPushTokenConfiguration.cs b/Govor.Data/Configurations/UserPushTokenConfiguration.cs index 029263e..203408a 100644 --- a/Govor.Data/Configurations/UserPushTokenConfiguration.cs +++ b/Govor.Data/Configurations/UserPushTokenConfiguration.cs @@ -10,9 +10,24 @@ public class UserPushTokenConfiguration : IEntityTypeConfiguration t.Id); - builder.HasIndex(x => x.Token).IsUnique(); - builder.HasIndex(x => x.UserSessionId).IsUnique(); - builder.HasIndex(x => x.UserId).IsUnique(); + builder.HasIndex(x => x.Token) + .IsUnique(); + + builder.HasIndex(x => x.UserSessionId) + .IsUnique(); + builder.HasIndex(x => new { x.UserId, x.IsActive }); + + builder.Property(x => x.Token) + .IsRequired() + .HasMaxLength(512); + + builder.Property(x => x.Platform) + .IsRequired() + .HasMaxLength(50); + + builder.Property(x => x.Provider) + .IsRequired() + .HasMaxLength(50); } } \ No newline at end of file diff --git a/Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.Designer.cs b/Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.Designer.cs new file mode 100644 index 0000000..c7439d1 --- /dev/null +++ b/Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.Designer.cs @@ -0,0 +1,838 @@ +// +using System; +using Govor.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Govor.Data.Migrations +{ + [DbContext(typeof(GovorDbContext))] + [Migration("20260301120522_FixPushTokensIndexs")] + partial class FixPushTokensIndexs + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Govor.Core.Models.ChatGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ImageId") + .HasColumnType("uuid"); + + b.Property("IsChannel") + .HasColumnType("boolean"); + + b.Property("IsPrivate") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("ChatGroups"); + }); + + modelBuilder.Entity("Govor.Core.Models.Friendship", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddresseeId") + .HasColumnType("uuid"); + + b.Property("RequesterId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AddresseeId"); + + b.HasIndex("RequesterId"); + + b.ToTable("Friendships"); + }); + + modelBuilder.Entity("Govor.Core.Models.GroupAdmins", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GroupId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.ToTable("GroupAdmins"); + }); + + modelBuilder.Entity("Govor.Core.Models.GroupInvitation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("EndDate") + .HasColumnType("timestamp with time zone"); + + b.Property("GroupId") + .HasColumnType("uuid"); + + b.Property("InvitationCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("MaxParticipants") + .HasColumnType("integer"); + + b.Property("UserMakerId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("UserMakerId"); + + b.ToTable("GroupInvitations"); + }); + + modelBuilder.Entity("Govor.Core.Models.GroupMembership", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GroupId") + .HasColumnType("uuid"); + + b.Property("InvitationId") + .HasColumnType("uuid"); + + b.Property("IsBanned") + .HasColumnType("boolean"); + + b.Property("MemberSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("InvitationId"); + + b.ToTable("GroupMemberships"); + }); + + modelBuilder.Entity("Govor.Core.Models.Invitation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasColumnType("text"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("EndDate") + .HasColumnType("timestamp with time zone"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.Property("MaxParticipants") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Invitations"); + }); + + modelBuilder.Entity("Govor.Core.Models.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("MediaType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MineType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("OwnerId") + .HasColumnType("uuid"); + + b.Property("OwnerType") + .HasColumnType("integer"); + + b.Property("UploaderId") + .HasColumnType("uuid"); + + b.Property("Url") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("MediaFiles"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.MediaAttachments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaFileId") + .HasColumnType("uuid"); + + b.Property("MessageId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MediaFileId"); + + b.HasIndex("MessageId"); + + b.ToTable("MediaAttachments"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.Message", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChatGroupId") + .HasColumnType("uuid"); + + b.Property("EditedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("EncryptedContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsEdited") + .HasColumnType("boolean"); + + b.Property("PrivateChatId") + .HasColumnType("uuid"); + + b.Property("RecipientId") + .HasColumnType("uuid"); + + b.Property("RecipientType") + .HasColumnType("integer"); + + b.Property("ReplyToMessageId") + .HasColumnType("uuid"); + + b.Property("SenderId") + .HasColumnType("uuid"); + + b.Property("SentAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ChatGroupId"); + + b.HasIndex("PrivateChatId"); + + b.HasIndex("RecipientId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.MessageReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MessageId") + .HasColumnType("uuid"); + + b.Property("ReactedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ReactionCode") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("MessageId", "UserId") + .IsUnique(); + + b.ToTable("MessageReactions"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.MessageView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MessageId") + .HasColumnType("uuid"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("ViewedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("MessageId", "UserId") + .IsUnique(); + + b.ToTable("MessageViews"); + }); + + modelBuilder.Entity("Govor.Core.Models.PrivateChat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("UserAId") + .HasColumnType("uuid"); + + b.Property("UserBId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("PrivateChats"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Admin", b => + { + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("UserId"); + + b.ToTable("Admins"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.OneTimePreKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsUsed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("UploadedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserCryptoSessionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UploadedAt"); + + b.HasIndex("UserCryptoSessionId", "IsUsed"); + + b.ToTable("OneTimePreKeys"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.SignedPreKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("PublicSignedPreKey") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("SignedPreKeySignature") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("UserCryptoSessionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserCryptoSessionId") + .IsUnique(); + + b.ToTable("SignedPreKeys"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.UserCryptoSession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("PublicIdentityKey") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("UserSessionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserSessionId") + .IsUnique(); + + b.ToTable("UserCryptoSessions"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedOn") + .HasColumnType("date"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("IconId") + .HasColumnType("uuid"); + + b.Property("InviteId") + .HasColumnType("uuid"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("WasOnline") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatedOn"); + + b.HasIndex("InviteId"); + + b.HasIndex("Username") + .IsUnique(); + + b.HasIndex("WasOnline"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.UserPushToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("LastUsedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Provider") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("UserSessionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserSessionId") + .IsUnique(); + + b.HasIndex("UserId", "IsActive"); + + b.ToTable("UserPushTokens"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.UserSession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceInfo") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsRevoked") + .HasColumnType("boolean"); + + b.Property("RefreshTokenHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("RefreshTokenHash") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("UserSessions"); + }); + + modelBuilder.Entity("Govor.Core.Models.Friendship", b => + { + b.HasOne("Govor.Core.Models.Users.User", "Addressee") + .WithMany("ReceivedFriendRequests") + .HasForeignKey("AddresseeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Govor.Core.Models.Users.User", "Requester") + .WithMany("SentFriendRequests") + .HasForeignKey("RequesterId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Addressee"); + + b.Navigation("Requester"); + }); + + modelBuilder.Entity("Govor.Core.Models.GroupAdmins", b => + { + b.HasOne("Govor.Core.Models.ChatGroup", null) + .WithMany("Admins") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Govor.Core.Models.GroupInvitation", b => + { + b.HasOne("Govor.Core.Models.ChatGroup", null) + .WithMany("InviteCodes") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Govor.Core.Models.Users.User", "UserMaker") + .WithMany() + .HasForeignKey("UserMakerId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("UserMaker"); + }); + + modelBuilder.Entity("Govor.Core.Models.GroupMembership", b => + { + b.HasOne("Govor.Core.Models.ChatGroup", null) + .WithMany("Members") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Govor.Core.Models.GroupInvitation", null) + .WithMany() + .HasForeignKey("InvitationId") + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.MediaAttachments", b => + { + b.HasOne("Govor.Core.Models.MediaFile", "MediaFile") + .WithMany() + .HasForeignKey("MediaFileId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Govor.Core.Models.Messages.Message", "Message") + .WithMany("MediaAttachments") + .HasForeignKey("MessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaFile"); + + b.Navigation("Message"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.Message", b => + { + b.HasOne("Govor.Core.Models.ChatGroup", null) + .WithMany("Messages") + .HasForeignKey("ChatGroupId"); + + b.HasOne("Govor.Core.Models.PrivateChat", null) + .WithMany("Messages") + .HasForeignKey("PrivateChatId"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.MessageReaction", b => + { + b.HasOne("Govor.Core.Models.Messages.Message", "Message") + .WithMany("Reactions") + .HasForeignKey("MessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Govor.Core.Models.Users.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Message"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.MessageView", b => + { + b.HasOne("Govor.Core.Models.Messages.Message", null) + .WithMany("MessageViews") + .HasForeignKey("MessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Admin", b => + { + b.HasOne("Govor.Core.Models.Users.User", "User") + .WithOne() + .HasForeignKey("Govor.Core.Models.Users.Admin", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.OneTimePreKey", b => + { + b.HasOne("Govor.Core.Models.Users.Crypto.UserCryptoSession", "UserCryptoSession") + .WithMany("OneTimePreKeys") + .HasForeignKey("UserCryptoSessionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserCryptoSession"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.SignedPreKey", b => + { + b.HasOne("Govor.Core.Models.Users.Crypto.UserCryptoSession", "UserCryptoSession") + .WithOne("SignedPreKey") + .HasForeignKey("Govor.Core.Models.Users.Crypto.SignedPreKey", "UserCryptoSessionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserCryptoSession"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.UserCryptoSession", b => + { + b.HasOne("Govor.Core.Models.Users.UserSession", "UserSession") + .WithOne("CryptoSession") + .HasForeignKey("Govor.Core.Models.Users.Crypto.UserCryptoSession", "UserSessionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("UserSession"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.User", b => + { + b.HasOne("Govor.Core.Models.Invitation", "Invite") + .WithMany("Users") + .HasForeignKey("InviteId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Invite"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.UserSession", b => + { + b.HasOne("Govor.Core.Models.Users.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Govor.Core.Models.ChatGroup", b => + { + b.Navigation("Admins"); + + b.Navigation("InviteCodes"); + + b.Navigation("Members"); + + b.Navigation("Messages"); + }); + + modelBuilder.Entity("Govor.Core.Models.Invitation", b => + { + b.Navigation("Users"); + }); + + modelBuilder.Entity("Govor.Core.Models.Messages.Message", b => + { + b.Navigation("MediaAttachments"); + + b.Navigation("MessageViews"); + + b.Navigation("Reactions"); + }); + + modelBuilder.Entity("Govor.Core.Models.PrivateChat", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.Crypto.UserCryptoSession", b => + { + b.Navigation("OneTimePreKeys"); + + b.Navigation("SignedPreKey") + .IsRequired(); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.User", b => + { + b.Navigation("ReceivedFriendRequests"); + + b.Navigation("SentFriendRequests"); + }); + + modelBuilder.Entity("Govor.Core.Models.Users.UserSession", b => + { + b.Navigation("CryptoSession") + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.cs b/Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.cs new file mode 100644 index 0000000..d57185e --- /dev/null +++ b/Govor.Data/Migrations/20260301120522_FixPushTokensIndexs.cs @@ -0,0 +1,82 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Govor.Data.Migrations +{ + /// + public partial class FixPushTokensIndexs : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_UserPushTokens_UserId", + table: "UserPushTokens"); + + migrationBuilder.AlterColumn( + name: "Token", + table: "UserPushTokens", + type: "character varying(512)", + maxLength: 512, + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Provider", + table: "UserPushTokens", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Platform", + table: "UserPushTokens", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Token", + table: "UserPushTokens", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(512)", + oldMaxLength: 512); + + migrationBuilder.AlterColumn( + name: "Provider", + table: "UserPushTokens", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "Platform", + table: "UserPushTokens", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.CreateIndex( + name: "IX_UserPushTokens_UserId", + table: "UserPushTokens", + column: "UserId", + unique: true); + } + } +} diff --git a/Govor.Data/Migrations/GovorDbContextModelSnapshot.cs b/Govor.Data/Migrations/GovorDbContextModelSnapshot.cs index 3e7a42b..7eee105 100644 --- a/Govor.Data/Migrations/GovorDbContextModelSnapshot.cs +++ b/Govor.Data/Migrations/GovorDbContextModelSnapshot.cs @@ -523,15 +523,18 @@ namespace Govor.Data.Migrations b.Property("Platform") .IsRequired() - .HasColumnType("text"); + .HasMaxLength(50) + .HasColumnType("character varying(50)"); b.Property("Provider") .IsRequired() - .HasColumnType("text"); + .HasMaxLength(50) + .HasColumnType("character varying(50)"); b.Property("Token") .IsRequired() - .HasColumnType("text"); + .HasMaxLength(512) + .HasColumnType("character varying(512)"); b.Property("UpdatedAt") .HasColumnType("timestamp with time zone"); @@ -547,9 +550,6 @@ namespace Govor.Data.Migrations b.HasIndex("Token") .IsUnique(); - b.HasIndex("UserId") - .IsUnique(); - b.HasIndex("UserSessionId") .IsUnique(); diff --git a/Govor.Data/Repositories/PushTokenRepository.cs b/Govor.Data/Repositories/PushTokenRepository.cs index 142adfc..61da51b 100644 --- a/Govor.Data/Repositories/PushTokenRepository.cs +++ b/Govor.Data/Repositories/PushTokenRepository.cs @@ -54,7 +54,7 @@ public class PushTokenRepository : IPushTokenRepository { if (userId == Guid.Empty) throw new ArgumentException("UserId cannot be empty", nameof(userId)); - + if (string.IsNullOrWhiteSpace(token)) throw new ArgumentException("Token cannot be empty", nameof(token)); @@ -62,7 +62,7 @@ public class PushTokenRepository : IPushTokenRepository throw new ArgumentException("Platform cannot be empty", nameof(platform)); var existing = await _context.UserPushTokens - .FirstOrDefaultAsync(t => t.Token == token); + .FirstOrDefaultAsync(t => t.UserSessionId == sessionId); if (existing != null) {