2022-11-28 05:45:25 +00:00
|
|
|
package db
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-01-17 09:33:18 +00:00
|
|
|
stdpath "path"
|
2022-12-10 11:28:34 +00:00
|
|
|
"strings"
|
2022-11-28 05:45:25 +00:00
|
|
|
|
2022-12-16 08:51:36 +00:00
|
|
|
"github.com/alist-org/alist/v3/internal/conf"
|
2022-11-28 05:45:25 +00:00
|
|
|
"github.com/alist-org/alist/v3/internal/model"
|
2022-12-05 12:23:37 +00:00
|
|
|
"github.com/alist-org/alist/v3/pkg/utils"
|
2022-11-28 05:45:25 +00:00
|
|
|
"github.com/pkg/errors"
|
2022-12-12 12:20:01 +00:00
|
|
|
"gorm.io/gorm"
|
2022-11-28 05:45:25 +00:00
|
|
|
)
|
|
|
|
|
2022-12-12 12:20:01 +00:00
|
|
|
func whereInParent(parent string) *gorm.DB {
|
2022-12-14 02:37:09 +00:00
|
|
|
if parent == "/" {
|
|
|
|
return db.Where("1 = 1")
|
|
|
|
}
|
2022-12-12 12:20:01 +00:00
|
|
|
return db.Where(fmt.Sprintf("%s LIKE ?", columnName("parent")),
|
|
|
|
fmt.Sprintf("%s/%%", parent)).
|
2022-12-14 02:37:09 +00:00
|
|
|
Or(fmt.Sprintf("%s = ?", columnName("parent")), parent)
|
2022-12-12 12:20:01 +00:00
|
|
|
}
|
|
|
|
|
2022-11-28 05:45:25 +00:00
|
|
|
func CreateSearchNode(node *model.SearchNode) error {
|
|
|
|
return db.Create(node).Error
|
|
|
|
}
|
|
|
|
|
2022-12-05 05:28:39 +00:00
|
|
|
func BatchCreateSearchNodes(nodes *[]model.SearchNode) error {
|
|
|
|
return db.CreateInBatches(nodes, 1000).Error
|
|
|
|
}
|
|
|
|
|
2023-01-17 09:33:18 +00:00
|
|
|
func DeleteSearchNodesByParent(path string) error {
|
|
|
|
path = utils.FixAndCleanPath(path)
|
|
|
|
err := db.Where(whereInParent(path)).Delete(&model.SearchNode{}).Error
|
2022-12-05 12:23:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-01-17 09:33:18 +00:00
|
|
|
dir, name := stdpath.Split(path)
|
2022-12-05 12:23:37 +00:00
|
|
|
return db.Where(fmt.Sprintf("%s = ? AND %s = ?",
|
|
|
|
columnName("parent"), columnName("name")),
|
2022-12-17 11:49:05 +00:00
|
|
|
dir, name).Delete(&model.SearchNode{}).Error
|
2022-11-28 05:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func ClearSearchNodes() error {
|
|
|
|
return db.Where("1 = 1").Delete(&model.SearchNode{}).Error
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetSearchNodesByParent(parent string) ([]model.SearchNode, error) {
|
|
|
|
var nodes []model.SearchNode
|
|
|
|
if err := db.Where(fmt.Sprintf("%s = ?",
|
|
|
|
columnName("parent")), parent).Find(&nodes).Error; err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return nodes, nil
|
|
|
|
}
|
|
|
|
|
2023-01-06 17:40:49 +00:00
|
|
|
func SearchNode(req model.SearchReq, useFullText bool) ([]model.SearchNode, int64, error) {
|
2022-12-16 08:51:36 +00:00
|
|
|
var searchDB *gorm.DB
|
2023-01-06 17:40:49 +00:00
|
|
|
if !useFullText || conf.Conf.Database.Type == "sqlite3" {
|
2022-12-16 08:51:36 +00:00
|
|
|
keywordsClause := db.Where("1 = 1")
|
2022-12-21 11:19:37 +00:00
|
|
|
for _, keyword := range strings.Fields(req.Keywords) {
|
2022-12-16 08:51:36 +00:00
|
|
|
keywordsClause = keywordsClause.Where("name LIKE ?", fmt.Sprintf("%%%s%%", keyword))
|
|
|
|
}
|
|
|
|
searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).Where(keywordsClause)
|
2023-01-06 17:40:49 +00:00
|
|
|
} else {
|
|
|
|
switch conf.Conf.Database.Type {
|
|
|
|
case "mysql":
|
|
|
|
searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).
|
|
|
|
Where("MATCH (name) AGAINST (? IN BOOLEAN MODE)", "'*"+req.Keywords+"*'")
|
|
|
|
case "postgres":
|
|
|
|
searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).
|
|
|
|
Where("to_tsvector(name) @@ to_tsquery(?)", strings.Join(strings.Fields(req.Keywords), " & "))
|
|
|
|
}
|
2022-12-10 11:28:34 +00:00
|
|
|
}
|
2023-08-06 07:13:23 +00:00
|
|
|
|
|
|
|
if req.Scope != 0 {
|
|
|
|
isDir := req.Scope == 1
|
|
|
|
searchDB.Where(db.Where("is_dir = ?", isDir))
|
|
|
|
}
|
|
|
|
|
2022-11-28 05:45:25 +00:00
|
|
|
var count int64
|
|
|
|
if err := searchDB.Count(&count).Error; err != nil {
|
2023-06-06 11:34:10 +00:00
|
|
|
return nil, 0, errors.Wrapf(err, "failed get search items count")
|
2022-11-28 05:45:25 +00:00
|
|
|
}
|
|
|
|
var files []model.SearchNode
|
2023-08-06 07:13:23 +00:00
|
|
|
if err := searchDB.Order("name asc").Offset((req.Page - 1) * req.PerPage).Limit(req.PerPage).
|
|
|
|
Find(&files).Error; err != nil {
|
2022-11-28 05:45:25 +00:00
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
return files, count, nil
|
|
|
|
}
|