Feat: room list search

pull/21/head
zijiren233 2 years ago
parent 160a15d7b1
commit 379ef5d85b

@ -119,7 +119,7 @@ func InitDatabase(ctx context.Context) error {
log.Fatalf("failed to get sqlDB: %s", err.Error())
}
initRawDB(sqlDB)
return db.Init(d)
return db.Init(d, conf.Conf.Database.Type)
}
func newDBLogger() logger.Interface {

@ -1,17 +1,24 @@
package db
import (
"fmt"
log "github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/internal/conf"
"github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/utils"
_ "github.com/synctv-org/synctv/utils/fastJSONSerializer"
"gorm.io/gorm"
)
var db *gorm.DB
var (
db *gorm.DB
dbType conf.DatabaseType
)
func Init(d *gorm.DB) error {
func Init(d *gorm.DB, t conf.DatabaseType) error {
db = d
dbType = t
return AutoMigrate(new(model.Movie), new(model.Room), new(model.User), new(model.RoomUserRelation), new(model.UserProvider))
}
@ -87,3 +94,82 @@ func OrderByIDAsc(db *gorm.DB) *gorm.DB {
func OrderByIDDesc(db *gorm.DB) *gorm.DB {
return db.Order("id desc")
}
func WithUser(db *gorm.DB) *gorm.DB {
return db.Preload("User")
}
func WithUserAndProvider(db *gorm.DB) *gorm.DB {
return db.Preload("User").Preload("User.Provider")
}
func WhereRoomID(roomID uint) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("room_id = ?", roomID)
}
}
func WhereUserID(userID uint) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("user_id = ?", userID)
}
}
func WhereCreatorID(creatorID uint) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("creator_id = ?", creatorID)
}
}
// column cannot be a user parameter
func WhereEqual(column string, value interface{}) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where(fmt.Sprintf("%s = ?", column), value)
}
}
// column cannot be a user parameter
func WhereLike(column string, value string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
switch dbType {
case conf.DatabaseTypePostgres:
return db.Where(fmt.Sprintf("%s ILIKE ?", column), utils.LIKE(value))
default:
return db.Where(fmt.Sprintf("%s LIKE ?", column), utils.LIKE(value))
}
}
}
func WhereRoomNameLikeOrCreatorIn(name string, ids []uint) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
switch dbType {
case conf.DatabaseTypePostgres:
return db.Where("name ILIKE ? OR creator_id IN ?", utils.LIKE(name), ids)
default:
return db.Where("name LIKE ? OR creator_id IN ?", utils.LIKE(name), ids)
}
}
}
func WhereRoomNameLike(name string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
switch dbType {
case conf.DatabaseTypePostgres:
return db.Where("name ILIKE ?", utils.LIKE(name))
default:
return db.Where("name LIKE ?", utils.LIKE(name))
}
}
}
func WhereCreatorIDIn(ids []uint) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Where("creator_id IN ?", ids)
}
}
func Select(columns ...string) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
return db.Select(columns)
}
}

@ -165,7 +165,7 @@ func GetAllRooms(scopes ...func(*gorm.DB) *gorm.DB) []*model.Room {
func GetAllRoomsWithoutHidden(scopes ...func(*gorm.DB) *gorm.DB) []*model.Room {
rooms := []*model.Room{}
db.Preload("Setting").Where("setting.hidden = ?", false).Scopes(scopes...).Find(&rooms)
db.Preload("Setting", "hidden = ?", false).Scopes(scopes...).Find(&rooms)
return rooms
}

@ -2,6 +2,7 @@ package db
import (
"errors"
"fmt"
"github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/provider"
@ -91,6 +92,18 @@ func GetUserByUsername(username string) (*model.User, error) {
return u, err
}
func GetUserByUsernameLike(username string, scopes ...func(*gorm.DB) *gorm.DB) []*model.User {
var users []*model.User
db.Where(`username LIKE ?`, fmt.Sprintf("%%%s%%", username)).Scopes(scopes...).Find(&users)
return users
}
func GerUsersIDByUsernameLike(username string, scopes ...func(*gorm.DB) *gorm.DB) []uint {
var ids []uint
db.Model(&model.User{}).Where(`username LIKE ?`, fmt.Sprintf("%%%s%%", username)).Scopes(scopes...).Pluck("id", &ids)
return ids
}
func GetUserByID(id uint) (*model.User, error) {
u := &model.User{}
err := db.Where("id = ?", id).First(u).Error
@ -100,9 +113,9 @@ func GetUserByID(id uint) (*model.User, error) {
return u, err
}
func GetUsersByRoomID(roomID uint) ([]model.User, error) {
func GetUsersByRoomID(roomID uint, scopes ...func(*gorm.DB) *gorm.DB) ([]model.User, error) {
users := []model.User{}
err := db.Model(&model.RoomUserRelation{}).Where("room_id = ?", roomID).Find(&users).Error
err := db.Model(&model.RoomUserRelation{}).Where("room_id = ?", roomID).Scopes(scopes...).Find(&users).Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
return users, errors.New("room not found")
}

@ -66,6 +66,9 @@ func RoomList(ctx *gin.Context) {
var desc = ctx.DefaultQuery("sort", "desc") == "desc"
// search mode, all, name, creator
var search = ctx.DefaultQuery("search", "all")
scopes := []func(db *gorm.DB) *gorm.DB{
db.Paginate(page, pageSize),
}
@ -102,21 +105,51 @@ func RoomList(ctx *gin.Context) {
} else {
scopes = append(scopes, db.OrderByCreatedAtAsc)
}
resp = genRoomsResp(resp, scopes...)
if keyword := ctx.Query("keyword"); keyword != "" {
switch search {
case "all":
scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword)))
case "name":
scopes = append(scopes, db.WhereRoomNameLike(keyword))
case "creator":
scopes = append(scopes, db.WhereCreatorIDIn(db.GerUsersIDByUsernameLike(keyword)))
}
}
resp = genRoomListResp(resp, scopes...)
case "roomName":
if desc {
scopes = append(scopes, db.OrderByDesc("name"))
} else {
scopes = append(scopes, db.OrderByAsc("name"))
}
resp = genRoomsResp(resp, scopes...)
if keyword := ctx.Query("keyword"); keyword != "" {
switch search {
case "all":
scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword)))
case "name":
scopes = append(scopes, db.WhereRoomNameLike(keyword))
case "creator":
scopes = append(scopes, db.WhereCreatorIDIn(db.GerUsersIDByUsernameLike(keyword)))
}
}
resp = genRoomListResp(resp, scopes...)
case "roomId":
if desc {
scopes = append(scopes, db.OrderByIDDesc)
} else {
scopes = append(scopes, db.OrderByIDAsc)
}
resp = genRoomsResp(resp, scopes...)
if keyword := ctx.Query("keyword"); keyword != "" {
switch search {
case "all":
scopes = append(scopes, db.WhereRoomNameLikeOrCreatorIn(keyword, db.GerUsersIDByUsernameLike(keyword)))
case "name":
scopes = append(scopes, db.WhereRoomNameLike(keyword))
case "creator":
scopes = append(scopes, db.WhereCreatorIDIn(db.GerUsersIDByUsernameLike(keyword)))
}
}
resp = genRoomListResp(resp, scopes...)
default:
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support order"))
return
@ -128,8 +161,8 @@ func RoomList(ctx *gin.Context) {
}))
}
func genRoomsResp(resp []*model.RoomListResp, scopes ...func(db *gorm.DB) *gorm.DB) []*model.RoomListResp {
for _, r := range db.GetAllRooms(scopes...) {
func genRoomListResp(resp []*model.RoomListResp, scopes ...func(db *gorm.DB) *gorm.DB) []*model.RoomListResp {
for _, r := range db.GetAllRoomsWithoutHidden(scopes...) {
resp = append(resp, &model.RoomListResp{
RoomId: r.ID,
RoomName: r.Name,

@ -1,6 +1,7 @@
package utils
import (
"fmt"
"math/rand"
"net"
"net/url"
@ -244,3 +245,7 @@ func OptFilePath(filePath *string) {
*filePath = filepath.Join(flags.DataDir, *filePath)
}
}
func LIKE(s string) string {
return fmt.Sprintf("%%%s%%", s)
}

Loading…
Cancel
Save