From 71f47f9ffc9771d41646bb45685793e550379ee8 Mon Sep 17 00:00:00 2001 From: Michael Wolfendale <4563722+wolfendale@users.noreply.github.com> Date: Sun, 23 Jun 2024 13:42:55 +0100 Subject: [PATCH] fix: remove n+1 queries --- database/wiiu/get_user_block_list.go | 44 +++++++--- database/wiiu/get_user_friend_list.go | 84 +++++++++++++------ database/wiiu/get_user_friend_requests_in.go | 42 ++++++++-- database/wiiu/get_user_friend_requests_out.go | 42 ++++++++-- 4 files changed, 159 insertions(+), 53 deletions(-) diff --git a/database/wiiu/get_user_block_list.go b/database/wiiu/get_user_block_list.go index acca753..8b4d1fb 100644 --- a/database/wiiu/get_user_block_list.go +++ b/database/wiiu/get_user_block_list.go @@ -13,7 +13,16 @@ func GetUserBlockList(pid uint32) (*types.List[*friends_wiiu_types.BlacklistedPr blockList := types.NewList[*friends_wiiu_types.BlacklistedPrincipal]() blockList.Type = friends_wiiu_types.NewBlacklistedPrincipal() - rows, err := database.Manager.Query(`SELECT blocked_pid, title_id, title_version, date FROM wiiu.blocks WHERE blocker_pid=$1`, pid) + rows, err := database.Manager.Query(` + SELECT + b.blocked_pid, b.title_id, b.title_version, b.date, + bi.username, bi.unknown, + mii.name, mii.unknown1, mii.unknown2, mii.data, mii.unknown_datetime + FROM wiiu.blocks AS b + INNER JOIN wiiu.principal_basic_info AS bi ON bi.pid = b.blocked_pid + INNER JOIN wiiu.mii AS mii ON mii.pid = b.blocked_pid + WHERE blocker_pid=$1 + `, pid) if err != nil { if err == sql.ErrNoRows { return blockList, database.ErrBlacklistNotFound @@ -24,25 +33,40 @@ func GetUserBlockList(pid uint32) (*types.List[*friends_wiiu_types.BlacklistedPr defer rows.Close() for rows.Next() { - var pid uint32 + var blockedPID uint32 var titleID uint64 var titleVersion uint16 var date uint64 - err := rows.Scan(&pid, &titleID, &titleVersion, &date) + var blockedNNID string + var unknown uint8 + + var miiName string + var miiUnknown1 uint8 + var miiUnknown2 uint8 + var miiData []byte + var miiDatetime uint64 + + err := rows.Scan(&blockedPID, &titleID, &titleVersion, &date, &blockedNNID, &unknown, &miiName, &miiUnknown1, &miiUnknown2, &miiData, &miiDatetime) if err != nil { return nil, err } - userInfo, err := GetUserPrincipalBasicInfo(pid) - if err != nil { - return nil, err - } + mii := friends_wiiu_types.NewMiiV2() + mii.Name = types.NewString(miiName) + mii.Unknown1 = types.NewPrimitiveU8(miiUnknown1) + mii.Unknown2 = types.NewPrimitiveU8(miiUnknown2) + mii.MiiData = types.NewBuffer(miiData) + mii.Datetime = types.NewDateTime(miiDatetime) + + principalBasicInfo := friends_wiiu_types.NewPrincipalBasicInfo() + principalBasicInfo.PID = types.NewPID(uint64(blockedPID)) + principalBasicInfo.NNID = types.NewString(blockedNNID) + principalBasicInfo.Unknown = types.NewPrimitiveU8(unknown) + principalBasicInfo.Mii = mii blacklistPrincipal := friends_wiiu_types.NewBlacklistedPrincipal() - - blacklistPrincipal.PrincipalBasicInfo = userInfo - + blacklistPrincipal.PrincipalBasicInfo = principalBasicInfo blacklistPrincipal.GameKey = friends_wiiu_types.NewGameKey() blacklistPrincipal.GameKey.TitleID = types.NewPrimitiveU64(titleID) blacklistPrincipal.GameKey.TitleVersion = types.NewPrimitiveU16(titleVersion) diff --git a/database/wiiu/get_user_friend_list.go b/database/wiiu/get_user_friend_list.go index 383af99..df39d32 100644 --- a/database/wiiu/get_user_friend_list.go +++ b/database/wiiu/get_user_friend_list.go @@ -14,7 +14,23 @@ func GetUserFriendList(pid uint32) (*types.List[*friends_wiiu_types.FriendInfo], friendList := types.NewList[*friends_wiiu_types.FriendInfo]() friendList.Type = friends_wiiu_types.NewFriendInfo() - rows, err := database.Manager.Query(`SELECT user2_pid, date FROM wiiu.friendships WHERE user1_pid=$1 AND active=true LIMIT 100`, pid) + rows, err := database.Manager.Query(` + SELECT + f.user2_pid, f.date, + u.comment, u.comment_changed, + u.last_online, + bi.username, bi.unknown, + ai.unknown1, ai.unknown2, + mii.name, mii.unknown1, mii.unknown2, mii.data, mii.unknown_datetime + FROM wiiu.friendships AS f + INNER JOIN wiiu.user_data AS u ON u.pid = f.user2_pid + INNER JOIN wiiu.principal_basic_info AS bi ON bi.pid = f.user2_pid + INNER JOIN wiiu.network_account_info AS ai ON ai.pid = f.user2_pid + INNER JOIN wiiu.mii AS mii ON mii.pid = f.user2_pid + WHERE f.user1_pid=$1 AND f.active=true + LIMIT 100 + `, pid) + if err != nil { if err == sql.ErrNoRows { return friendList, database.ErrEmptyList @@ -27,47 +43,61 @@ func GetUserFriendList(pid uint32) (*types.List[*friends_wiiu_types.FriendInfo], for rows.Next() { var friendPID uint32 var date uint64 + var lastOnlineTime uint64 + var commentContents string + var commentChanged uint64 = 0 + var nnid string + var unknown uint8 + var unknown1 uint8 + var unknown2 uint8 + var miiName string + var miiUnknown1 uint8 + var miiUnknown2 uint8 + var miiData []byte + var miiDatetime uint64 - err := rows.Scan(&friendPID, &date) + err := rows.Scan(&friendPID, &date, &commentContents, &commentChanged, &lastOnlineTime, &nnid, &unknown, &unknown1, &unknown2, &miiName, &miiUnknown1, &miiUnknown2, &miiData, &miiDatetime) if err != nil { return nil, err } + comment := friends_wiiu_types.NewComment() + comment.Unknown = types.NewPrimitiveU8(0) + comment.Contents = types.NewString(commentContents) + comment.LastChanged = types.NewDateTime(commentChanged) + + mii := friends_wiiu_types.NewMiiV2() + mii.Name = types.NewString(miiName) + mii.Unknown1 = types.NewPrimitiveU8(miiUnknown1) + mii.Unknown2 = types.NewPrimitiveU8(miiUnknown2) + mii.MiiData = types.NewBuffer(miiData) + mii.Datetime = types.NewDateTime(miiDatetime) + + principalBasicInfo := friends_wiiu_types.NewPrincipalBasicInfo() + principalBasicInfo.PID = types.NewPID(uint64(friendPID)) + principalBasicInfo.NNID = types.NewString(nnid) + principalBasicInfo.Unknown = types.NewPrimitiveU8(unknown) + principalBasicInfo.Mii = mii + + nnaInfo := friends_wiiu_types.NewNNAInfo() + nnaInfo.Unknown1 = types.NewPrimitiveU8(unknown1) + nnaInfo.Unknown2 = types.NewPrimitiveU8(unknown2) + nnaInfo.PrincipalBasicInfo = principalBasicInfo + friendInfo := friends_wiiu_types.NewFriendInfo() - connectedUser, ok := globals.ConnectedUsers.Get(friendPID) + friendInfo.NNAInfo = nnaInfo + lastOnline := types.NewDateTime(0).Now() - - friendInfo.NNAInfo, err = GetUserNetworkAccountInfo(friendPID) - if err != nil { - return nil, err - } - + connectedUser, ok := globals.ConnectedUsers.Get(friendPID) if ok && connectedUser != nil { // * Online friendInfo.Presence = connectedUser.PresenceV2.Copy().(*friends_wiiu_types.NintendoPresenceV2) } else { // * Offline - var lastOnlineTime uint64 - row, err := database.Manager.QueryRow(`SELECT last_online FROM wiiu.user_data WHERE pid=$1`, friendPID) - if err != nil { - return nil, err - } - - err = row.Scan(&lastOnlineTime) - if err != nil { - return nil, err - } - lastOnline = types.NewDateTime(lastOnlineTime) // TODO - Change this } - status, err := GetUserComment(friendPID) - if err != nil { - return nil, err - } - - friendInfo.Status = status - + friendInfo.Status = comment friendInfo.BecameFriend = types.NewDateTime(date) friendInfo.LastOnline = lastOnline friendInfo.Unknown = types.NewPrimitiveU64(0) diff --git a/database/wiiu/get_user_friend_requests_in.go b/database/wiiu/get_user_friend_requests_in.go index 346ba1c..a7c61ae 100644 --- a/database/wiiu/get_user_friend_requests_in.go +++ b/database/wiiu/get_user_friend_requests_in.go @@ -14,7 +14,17 @@ func GetUserFriendRequestsIn(pid uint32) (*types.List[*friends_wiiu_types.Friend friendRequests := types.NewList[*friends_wiiu_types.FriendRequest]() friendRequests.Type = friends_wiiu_types.NewFriendRequest() - rows, err := database.Manager.Query(`SELECT id, sender_pid, sent_on, expires_on, message, received FROM wiiu.friend_requests WHERE recipient_pid=$1 AND accepted=false AND denied=false`, pid) + rows, err := database.Manager.Query(` + SELECT + fr.id, fr.sender_pid, fr.sent_on, fr.expires_on, fr.message, fr.received, + bi.username, bi.unknown, + mii.name, mii.unknown1, mii.unknown2, mii.data, mii.unknown_datetime + FROM wiiu.friend_requests AS fr + INNER JOIN wiiu.principal_basic_info AS bi ON bi.pid = fr.sender_pid + INNER JOIN wiiu.mii AS mii ON mii.pid = fr.sender_pid + WHERE recipient_pid=$1 AND accepted=false AND denied=false + LIMIT 100 + `, pid) if err != nil { if err == sql.ErrNoRows { return friendRequests, database.ErrEmptyList @@ -32,19 +42,35 @@ func GetUserFriendRequestsIn(pid uint32) (*types.List[*friends_wiiu_types.Friend var message string var received bool - err := rows.Scan(&id, &senderPID, &sentOn, &expiresOn, &message, &received) + var senderNNID string + var unknown uint8 + + var miiName string + var miiUnknown1 uint8 + var miiUnknown2 uint8 + var miiData []byte + var miiDatetime uint64 + + err := rows.Scan(&id, &senderPID, &sentOn, &expiresOn, &message, &received, &senderNNID, &unknown, &miiName, &miiUnknown1, &miiUnknown2, &miiData, &miiDatetime) if err != nil { return friendRequests, err } - userInfo, err := GetUserPrincipalBasicInfo(senderPID) - if err != nil { - return nil, err - } + mii := friends_wiiu_types.NewMiiV2() + mii.Name = types.NewString(miiName) + mii.Unknown1 = types.NewPrimitiveU8(miiUnknown1) + mii.Unknown2 = types.NewPrimitiveU8(miiUnknown2) + mii.MiiData = types.NewBuffer(miiData) + mii.Datetime = types.NewDateTime(miiDatetime) + + principalBasicInfo := friends_wiiu_types.NewPrincipalBasicInfo() + principalBasicInfo.PID = types.NewPID(uint64(senderPID)) + principalBasicInfo.NNID = types.NewString(senderNNID) + principalBasicInfo.Unknown = types.NewPrimitiveU8(unknown) + principalBasicInfo.Mii = mii friendRequest := friends_wiiu_types.NewFriendRequest() - - friendRequest.PrincipalInfo = userInfo + friendRequest.PrincipalInfo = principalBasicInfo friendRequest.Message = friends_wiiu_types.NewFriendRequestMessage() friendRequest.Message.FriendRequestID = types.NewPrimitiveU64(id) friendRequest.Message.Received = types.NewPrimitiveBool(received) diff --git a/database/wiiu/get_user_friend_requests_out.go b/database/wiiu/get_user_friend_requests_out.go index e318d9e..8d7829b 100644 --- a/database/wiiu/get_user_friend_requests_out.go +++ b/database/wiiu/get_user_friend_requests_out.go @@ -13,7 +13,17 @@ func GetUserFriendRequestsOut(pid uint32) (*types.List[*friends_wiiu_types.Frien friendRequests := types.NewList[*friends_wiiu_types.FriendRequest]() friendRequests.Type = friends_wiiu_types.NewFriendRequest() - rows, err := database.Manager.Query(`SELECT id, recipient_pid, sent_on, expires_on, message, received FROM wiiu.friend_requests WHERE sender_pid=$1 AND accepted=false`, pid) + rows, err := database.Manager.Query(` + SELECT + fr.id, fr.recipient_pid, fr.sent_on, fr.expires_on, fr.message, fr.received, + bi.username, bi.unknown, + mii.name, mii.unknown1, mii.unknown2, mii.data, mii.unknown_datetime + FROM wiiu.friend_requests AS fr + INNER JOIN wiiu.principal_basic_info AS bi ON bi.pid = fr.recipient_pid + INNER JOIN wiiu.mii AS mii ON mii.pid = fr.recipient_pid + WHERE sender_pid=$1 AND accepted=false + LIMIT 100 + `, pid) if err != nil { if err == sql.ErrNoRows { return friendRequests, database.ErrEmptyList @@ -31,19 +41,35 @@ func GetUserFriendRequestsOut(pid uint32) (*types.List[*friends_wiiu_types.Frien var message string var received bool - err := rows.Scan(&id, &recipientPID, &sentOn, &expiresOn, &message, &received) + var recipientNNID string + var unknown uint8 + + var miiName string + var miiUnknown1 uint8 + var miiUnknown2 uint8 + var miiData []byte + var miiDatetime uint64 + + err := rows.Scan(&id, &recipientPID, &sentOn, &expiresOn, &message, &received, &recipientNNID, &unknown, &miiName, &miiUnknown1, &miiUnknown2, &miiData, &miiDatetime) if err != nil { return friendRequests, err } - userInfo, err := GetUserPrincipalBasicInfo(recipientPID) - if err != nil { - return nil, err - } + mii := friends_wiiu_types.NewMiiV2() + mii.Name = types.NewString(miiName) + mii.Unknown1 = types.NewPrimitiveU8(miiUnknown1) + mii.Unknown2 = types.NewPrimitiveU8(miiUnknown2) + mii.MiiData = types.NewBuffer(miiData) + mii.Datetime = types.NewDateTime(miiDatetime) + + principalBasicInfo := friends_wiiu_types.NewPrincipalBasicInfo() + principalBasicInfo.PID = types.NewPID(uint64(recipientPID)) + principalBasicInfo.NNID = types.NewString(recipientNNID) + principalBasicInfo.Unknown = types.NewPrimitiveU8(unknown) + principalBasicInfo.Mii = mii friendRequest := friends_wiiu_types.NewFriendRequest() - - friendRequest.PrincipalInfo = userInfo + friendRequest.PrincipalInfo = principalBasicInfo friendRequest.Message = friends_wiiu_types.NewFriendRequestMessage() friendRequest.Message.FriendRequestID = types.NewPrimitiveU64(id) friendRequest.Message.Received = types.NewPrimitiveBool(received)