Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/db/searchnode.go
1560 views
1
package db
2
3
import (
4
"fmt"
5
stdpath "path"
6
"strings"
7
8
"github.com/alist-org/alist/v3/internal/conf"
9
"github.com/alist-org/alist/v3/internal/model"
10
"github.com/alist-org/alist/v3/pkg/utils"
11
"github.com/pkg/errors"
12
"gorm.io/gorm"
13
)
14
15
func whereInParent(parent string) *gorm.DB {
16
if parent == "/" {
17
return db.Where("1 = 1")
18
}
19
return db.Where(fmt.Sprintf("%s LIKE ?", columnName("parent")),
20
fmt.Sprintf("%s/%%", parent)).
21
Or(fmt.Sprintf("%s = ?", columnName("parent")), parent)
22
}
23
24
func CreateSearchNode(node *model.SearchNode) error {
25
return db.Create(node).Error
26
}
27
28
func BatchCreateSearchNodes(nodes *[]model.SearchNode) error {
29
return db.CreateInBatches(nodes, 1000).Error
30
}
31
32
func DeleteSearchNodesByParent(path string) error {
33
path = utils.FixAndCleanPath(path)
34
err := db.Where(whereInParent(path)).Delete(&model.SearchNode{}).Error
35
if err != nil {
36
return err
37
}
38
dir, name := stdpath.Split(path)
39
return db.Where(fmt.Sprintf("%s = ? AND %s = ?",
40
columnName("parent"), columnName("name")),
41
dir, name).Delete(&model.SearchNode{}).Error
42
}
43
44
func ClearSearchNodes() error {
45
return db.Where("1 = 1").Delete(&model.SearchNode{}).Error
46
}
47
48
func GetSearchNodesByParent(parent string) ([]model.SearchNode, error) {
49
var nodes []model.SearchNode
50
if err := db.Where(fmt.Sprintf("%s = ?",
51
columnName("parent")), parent).Find(&nodes).Error; err != nil {
52
return nil, err
53
}
54
return nodes, nil
55
}
56
57
func SearchNode(req model.SearchReq, useFullText bool) ([]model.SearchNode, int64, error) {
58
var searchDB *gorm.DB
59
if !useFullText || conf.Conf.Database.Type == "sqlite3" {
60
keywordsClause := db.Where("1 = 1")
61
for _, keyword := range strings.Fields(req.Keywords) {
62
keywordsClause = keywordsClause.Where("name LIKE ?", fmt.Sprintf("%%%s%%", keyword))
63
}
64
searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).Where(keywordsClause)
65
} else {
66
switch conf.Conf.Database.Type {
67
case "mysql":
68
searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).
69
Where("MATCH (name) AGAINST (? IN BOOLEAN MODE)", "'*"+req.Keywords+"*'")
70
case "postgres":
71
searchDB = db.Model(&model.SearchNode{}).Where(whereInParent(req.Parent)).
72
Where("to_tsvector(name) @@ to_tsquery(?)", strings.Join(strings.Fields(req.Keywords), " & "))
73
}
74
}
75
76
if req.Scope != 0 {
77
isDir := req.Scope == 1
78
searchDB.Where(db.Where("is_dir = ?", isDir))
79
}
80
81
var count int64
82
if err := searchDB.Count(&count).Error; err != nil {
83
return nil, 0, errors.Wrapf(err, "failed get search items count")
84
}
85
var files []model.SearchNode
86
if err := searchDB.Order("name asc").Offset((req.Page - 1) * req.PerPage).Limit(req.PerPage).
87
Find(&files).Error; err != nil {
88
return nil, 0, err
89
}
90
return files, count, nil
91
}
92
93