Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0

Optimize sql queries

Cette révision appartient à :
Eliot Whalan 2017-05-08 23:50:18 +10:00
Parent 525eeb752e
révision eca5079080
3 fichiers modifiés avec 26 ajouts et 22 suppressions

Voir le fichier

@ -10,7 +10,6 @@ import (
"github.com/ewhal/nyaa/network"
"github.com/ewhal/nyaa/router"
"github.com/ewhal/nyaa/util/log"
"github.com/ewhal/nyaa/util/search" // super hacky fix
"github.com/ewhal/nyaa/util/signals"
"net/http"
@ -61,7 +60,6 @@ func main() {
if len(config.TorrentFileStorage) > 0 {
os.MkdirAll(config.TorrentFileStorage, 0755)
}
search.Init(conf.DBType) // super hacky fix
RunServer(conf)
}
}

Voir le fichier

@ -6,8 +6,8 @@ import (
"github.com/ewhal/nyaa/db"
"github.com/ewhal/nyaa/model"
"github.com/ewhal/nyaa/util"
"github.com/jinzhu/gorm"
"strings"
"strconv"
)
type WhereParams struct {
@ -54,7 +54,6 @@ func GetTorrentById(id string) (model.Torrents, error) {
func GetTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) ([]model.Torrents, int) {
var torrents []model.Torrents
var dbQuery *gorm.DB
var count int
conditions := "torrent_hash IS NOT NULL" // filter out broken entries
if strings.HasPrefix(orderBy, "filesize") {
@ -69,15 +68,22 @@ func GetTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offs
params = parameters.Params
}
db.ORM.Model(&torrents).Where(conditions, params...).Count(&count)
dbQuery = db.ORM.Model(&torrents).Where(conditions, params...)
dbQuery := "SELECT * FROM torrents"
if conditions != "" {
dbQuery = dbQuery + " WHERE " + conditions
}
if strings.Contains(conditions, "torrent_name") {
dbQuery = "WITH t AS (SELECT * FROM torrents WHERE " + conditions + ") SELECT * FROM t"
}
if orderBy == "" { // default OrderBy
orderBy = "torrent_id DESC"
}
dbQuery = dbQuery + " ORDER BY " + orderBy
if limit != 0 || offset != 0 { // if limits provided
dbQuery = dbQuery.Limit(limit).Offset(offset)
dbQuery = dbQuery + " LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
}
dbQuery.Order(orderBy).Find(&torrents)
db.ORM.Raw(dbQuery, params...).Find(&torrents)
return torrents, count
}

Voir le fichier

@ -8,6 +8,8 @@ import (
"net/http"
"strconv"
"strings"
"unicode"
"unicode/utf8"
)
type SearchParam struct {
@ -19,17 +21,6 @@ type SearchParam struct {
Sort string
}
// super hacky fix:
var search_op string
func Init(backend string) {
if backend == "postgres" {
search_op = "ILIKE"
} else {
search_op = "LIKE"
}
}
func SearchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents, int) {
maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
if errConv != nil {
@ -81,10 +72,19 @@ func SearchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents,
}
parameters.Params = append(parameters.Params, search_param.Status)
}
searchQuerySplit := strings.Split(search_param.Query, " ")
for i, _ := range searchQuerySplit {
conditions = append(conditions, "torrent_name " + search_op + " ?")
parameters.Params = append(parameters.Params, "%"+searchQuerySplit[i]+"%")
searchQuerySplit := strings.Fields(search_param.Query)
for i, word := range searchQuerySplit {
firstRune, _ := utf8.DecodeRuneInString(word)
if len(word) == 1 && unicode.IsPunct(firstRune) {
// some queries have a single punctuation character
// which causes a full scan instead of using the index
// and yields no meaningful results.
// due to len() == 1 we're just looking at 1-byte/ascii
// punctuation characters.
continue
}
conditions = append(conditions, "torrent_name %> ?")
parameters.Params = append(parameters.Params, searchQuerySplit[i])
}
parameters.Conditions = strings.Join(conditions[:], " AND ")