Files
open-im-server/pkg/common/storage/controller/user.go
T

228 lines
9.6 KiB
Go
Raw Normal View History

2023-07-04 11:15:20 +08:00
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2023-06-30 09:45:02 +08:00
package controller
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
2024-04-19 22:23:08 +08:00
"github.com/openimsdk/tools/db/pagination"
"github.com/openimsdk/tools/db/tx"
"github.com/openimsdk/tools/utils/datautil"
2023-08-07 14:21:31 +08:00
"time"
2023-06-30 09:45:02 +08:00
2024-04-19 22:23:08 +08:00
"github.com/openimsdk/protocol/user"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
2023-06-30 09:45:02 +08:00
)
type UserDatabase interface {
// FindWithError Get the information of the specified user. If the userID is not found, it will also return an error
FindWithError(ctx context.Context, userIDs []string) (users []*model.User, err error)
// Find Get the information of the specified user If the userID is not found, no error will be returned
Find(ctx context.Context, userIDs []string) (users []*model.User, err error)
// Find userInfo By Nickname
FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error)
2024-01-03 17:24:02 +08:00
// Find notificationAccounts
FindNotification(ctx context.Context, level int64) (users []*model.User, err error)
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage
Create(ctx context.Context, users []*model.User) (err error)
// UpdateByMap update (zero value) external guarantee userID exists
UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error)
// FindUser
PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error)
2024-04-19 22:23:08 +08:00
// FindUser with keyword
PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, nickName string, pagination pagination.Pagination) (count int64, users []*model.User, err error)
// Page If not found, no error is returned
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error)
// IsExist true as long as one exists
2023-06-30 09:45:02 +08:00
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
// GetAllUserID Get all user IDs
GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error)
2023-12-26 10:15:15 +08:00
// Get user by userID
GetUserByID(ctx context.Context, userID string) (user *model.User, err error)
// InitOnce Inside the function, first query whether it exists in the storage, if it exists, do nothing; if it does not exist, insert it
InitOnce(ctx context.Context, users []*model.User) (err error)
// CountTotal Get the total number of users
2023-07-12 15:31:24 +08:00
CountTotal(ctx context.Context, before *time.Time) (int64, error)
// CountRangeEverydayTotal Get the user increment in the range
2023-06-30 09:45:02 +08:00
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
SortQuery(ctx context.Context, userIDName map[string]string, asc bool) ([]*model.User, error)
2024-04-19 22:23:08 +08:00
// CRUD user command
2024-01-10 10:27:03 +08:00
AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error
DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error
2024-01-10 10:27:03 +08:00
UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error
GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error)
2024-01-10 10:27:03 +08:00
GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error)
2023-06-30 09:45:02 +08:00
}
type userDatabase struct {
tx tx.Tx
userDB database.User
cache cache.UserCache
2023-06-30 09:45:02 +08:00
}
func NewUserDatabase(userDB database.User, cache cache.UserCache, tx tx.Tx) UserDatabase {
return &userDatabase{userDB: userDB, cache: cache, tx: tx}
2023-06-30 09:45:02 +08:00
}
func (u *userDatabase) InitOnce(ctx context.Context, users []*model.User) error {
// Extract user IDs from the given user models.
userIDs := datautil.Slice(users, func(e *model.User) string {
2023-06-30 09:45:02 +08:00
return e.UserID
})
// Find existing users in the database.
existingUsers, err := u.userDB.Find(ctx, userIDs)
2023-06-30 09:45:02 +08:00
if err != nil {
return err
}
// Determine which users are missing from the database.
missingUsers := datautil.SliceAnySub(users, existingUsers, func(e *model.User) string {
return e.UserID
})
// Create records for missing users.
if len(missingUsers) > 0 {
if err := u.userDB.Create(ctx, missingUsers); err != nil {
return err
}
2023-06-30 09:45:02 +08:00
}
2023-06-30 09:45:02 +08:00
return nil
}
// FindWithError Get the information of the specified user and return an error if the userID is not found.
func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (users []*model.User, err error) {
2024-07-23 10:26:04 +08:00
userIDs = datautil.Distinct(userIDs)
2023-06-30 09:45:02 +08:00
users, err = u.cache.GetUsersInfo(ctx, userIDs)
if err != nil {
return
}
if len(users) != len(userIDs) {
2024-04-19 22:23:08 +08:00
err = errs.ErrRecordNotFound.WrapMsg("userID not found")
2023-06-30 09:45:02 +08:00
}
return
}
// Find Get the information of the specified user. If the userID is not found, no error will be returned.
func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*model.User, err error) {
return u.cache.GetUsersInfo(ctx, userIDs)
2023-06-30 09:45:02 +08:00
}
func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error) {
return u.userDB.TakeByNickname(ctx, nickname)
}
func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users []*model.User, err error) {
2024-01-03 17:24:02 +08:00
return u.userDB.TakeNotification(ctx, level)
}
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage.
func (u *userDatabase) Create(ctx context.Context, users []*model.User) (err error) {
return u.tx.Transaction(ctx, func(ctx context.Context) error {
if err = u.userDB.Create(ctx, users); err != nil {
2023-06-30 09:45:02 +08:00
return err
}
return u.cache.DelUsersInfo(datautil.Slice(users, func(e *model.User) string {
return e.UserID
})...).ChainExecDel(ctx)
})
2023-06-30 09:45:02 +08:00
}
// UpdateByMap update (zero value) externally guarantees that userID exists.
func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) {
return u.tx.Transaction(ctx, func(ctx context.Context) error {
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
return err
}
return u.cache.DelUsersInfo(userID).ChainExecDel(ctx)
})
2023-06-30 09:45:02 +08:00
}
// Page Gets, returns no error if not found.
func (u *userDatabase) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error) {
return u.userDB.Page(ctx, pagination)
2023-06-30 09:45:02 +08:00
}
func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error) {
return u.userDB.PageFindUser(ctx, level1, level2, pagination)
}
func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*model.User, err error) {
return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, nickName, pagination)
2024-01-08 21:38:48 +08:00
}
// IsExist Does userIDs exist? As long as there is one, it will be true.
2023-06-30 09:45:02 +08:00
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
users, err := u.userDB.Find(ctx, userIDs)
if err != nil {
return false, err
}
if len(users) > 0 {
return true, nil
}
return false, nil
}
2023-08-04 21:38:30 +08:00
// GetAllUserID Get all user IDs.
func (u *userDatabase) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (total int64, userIDs []string, err error) {
return u.userDB.GetAllUserID(ctx, pagination)
2023-06-30 09:45:02 +08:00
}
func (u *userDatabase) GetUserByID(ctx context.Context, userID string) (user *model.User, err error) {
2024-07-16 10:46:21 +08:00
return u.cache.GetUserInfo(ctx, userID)
2023-12-26 10:15:15 +08:00
}
2023-08-04 21:38:30 +08:00
// CountTotal Get the total number of users.
2023-07-12 15:31:24 +08:00
func (u *userDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
return u.userDB.CountTotal(ctx, before)
2023-06-30 09:45:02 +08:00
}
2023-08-04 21:38:30 +08:00
// CountRangeEverydayTotal Get the user increment in the range.
func (u *userDatabase) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
2023-06-30 09:45:02 +08:00
return u.userDB.CountRangeEverydayTotal(ctx, start, end)
}
func (u *userDatabase) SortQuery(ctx context.Context, userIDName map[string]string, asc bool) ([]*model.User, error) {
return u.userDB.SortQuery(ctx, userIDName, asc)
}
2024-01-10 10:27:03 +08:00
func (u *userDatabase) AddUserCommand(ctx context.Context, userID string, Type int32, UUID string, value string, ex string) error {
return u.userDB.AddUserCommand(ctx, userID, Type, UUID, value, ex)
}
2024-04-19 22:23:08 +08:00
func (u *userDatabase) DeleteUserCommand(ctx context.Context, userID string, Type int32, UUID string) error {
return u.userDB.DeleteUserCommand(ctx, userID, Type, UUID)
}
2024-04-19 22:23:08 +08:00
2024-01-10 10:27:03 +08:00
func (u *userDatabase) UpdateUserCommand(ctx context.Context, userID string, Type int32, UUID string, val map[string]any) error {
return u.userDB.UpdateUserCommand(ctx, userID, Type, UUID, val)
}
2024-04-19 22:23:08 +08:00
func (u *userDatabase) GetUserCommands(ctx context.Context, userID string, Type int32) ([]*user.CommandInfoResp, error) {
commands, err := u.userDB.GetUserCommand(ctx, userID, Type)
return commands, err
}
2024-04-19 22:23:08 +08:00
2024-01-10 10:27:03 +08:00
func (u *userDatabase) GetAllUserCommands(ctx context.Context, userID string) ([]*user.AllCommandInfoResp, error) {
commands, err := u.userDB.GetAllUserCommand(ctx, userID)
return commands, err
}