Spaces:
Paused
Paused
| package db | |
| import ( | |
| "fmt" | |
| stdpath "path" | |
| "strings" | |
| "github.com/alist-org/alist/v3/internal/conf" | |
| "github.com/alist-org/alist/v3/internal/model" | |
| "github.com/alist-org/alist/v3/pkg/utils" | |
| "github.com/pkg/errors" | |
| "gorm.io/gorm" | |
| ) | |
| func whereInParent(parent string) *gorm.DB { | |
| if parent == "/" { | |
| return db.Where("1 = 1") | |
| } | |
| return db.Where(fmt.Sprintf("%s LIKE ?", columnName("parent")), | |
| fmt.Sprintf("%s/%%", parent)). | |
| Or(fmt.Sprintf("%s = ?", columnName("parent")), parent) | |
| } | |
| func CreateSearchNode(node *model.SearchNode) error { | |
| return db.Create(node).Error | |
| } | |
| func BatchCreateSearchNodes(nodes *[]model.SearchNode) error { | |
| return db.CreateInBatches(nodes, 1000).Error | |
| } | |
| func DeleteSearchNodesByParent(path string) error { | |
| path = utils.FixAndCleanPath(path) | |
| err := db.Where(whereInParent(path)).Delete(&model.SearchNode{}).Error | |
| if err != nil { | |
| return err | |
| } | |
| dir, name := stdpath.Split(path) | |
| return db.Where(fmt.Sprintf("%s = ? AND %s = ?", | |
| columnName("parent"), columnName("name")), | |
| dir, name).Delete(&model.SearchNode{}).Error | |
| } | |
| 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 | |
| } | |
| func SearchNode(req model.SearchReq, useFullText bool) ([]model.SearchNode, int64, error) { | |
| var searchDB *gorm.DB | |
| if !useFullText || conf.Conf.Database.Type == "sqlite3" { | |
| keywordsClause := db.Where("1 = 1") | |
| for _, keyword := range strings.Fields(req.Keywords) { | |
| keywordsClause = keywordsClause.Where("name LIKE ?", fmt.Sprintf("%%%s%%", keyword)) | |
| } | |
| searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).Where(keywordsClause) | |
| } 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), " & ")) | |
| } | |
| } | |
| if req.Scope != 0 { | |
| isDir := req.Scope == 1 | |
| searchDB.Where(db.Where("is_dir = ?", isDir)) | |
| } | |
| var count int64 | |
| if err := searchDB.Count(&count).Error; err != nil { | |
| return nil, 0, errors.Wrapf(err, "failed get search items count") | |
| } | |
| var files []model.SearchNode | |
| if err := searchDB.Order("name asc").Offset((req.Page - 1) * req.PerPage).Limit(req.PerPage). | |
| Find(&files).Error; err != nil { | |
| return nil, 0, err | |
| } | |
| return files, count, nil | |
| } | |