Optimize sql queries
Cette révision appartient à :
Parent
a9e414302e
révision
7e884fd04f
3 fichiers modifiés avec 26 ajouts et 22 suppressions
2
main.go
2
main.go
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/ewhal/nyaa/network"
|
"github.com/ewhal/nyaa/network"
|
||||||
"github.com/ewhal/nyaa/router"
|
"github.com/ewhal/nyaa/router"
|
||||||
"github.com/ewhal/nyaa/util/log"
|
"github.com/ewhal/nyaa/util/log"
|
||||||
"github.com/ewhal/nyaa/util/search" // super hacky fix
|
|
||||||
"github.com/ewhal/nyaa/util/signals"
|
"github.com/ewhal/nyaa/util/signals"
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -61,7 +60,6 @@ func main() {
|
||||||
if len(config.TorrentFileStorage) > 0 {
|
if len(config.TorrentFileStorage) > 0 {
|
||||||
os.MkdirAll(config.TorrentFileStorage, 0755)
|
os.MkdirAll(config.TorrentFileStorage, 0755)
|
||||||
}
|
}
|
||||||
search.Init(conf.DBType) // super hacky fix
|
|
||||||
RunServer(conf)
|
RunServer(conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"github.com/ewhal/nyaa/db"
|
"github.com/ewhal/nyaa/db"
|
||||||
"github.com/ewhal/nyaa/model"
|
"github.com/ewhal/nyaa/model"
|
||||||
"github.com/ewhal/nyaa/util"
|
"github.com/ewhal/nyaa/util"
|
||||||
"github.com/jinzhu/gorm"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WhereParams struct {
|
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) {
|
func GetTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) ([]model.Torrents, int) {
|
||||||
var torrents []model.Torrents
|
var torrents []model.Torrents
|
||||||
var dbQuery *gorm.DB
|
|
||||||
var count int
|
var count int
|
||||||
conditions := "torrent_hash IS NOT NULL" // filter out broken entries
|
conditions := "torrent_hash IS NOT NULL" // filter out broken entries
|
||||||
if strings.HasPrefix(orderBy, "filesize") {
|
if strings.HasPrefix(orderBy, "filesize") {
|
||||||
|
@ -69,15 +68,22 @@ func GetTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offs
|
||||||
params = parameters.Params
|
params = parameters.Params
|
||||||
}
|
}
|
||||||
db.ORM.Model(&torrents).Where(conditions, params...).Count(&count)
|
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
|
if orderBy == "" { // default OrderBy
|
||||||
orderBy = "torrent_id DESC"
|
orderBy = "torrent_id DESC"
|
||||||
}
|
}
|
||||||
|
dbQuery = dbQuery + " ORDER BY " + orderBy
|
||||||
if limit != 0 || offset != 0 { // if limits provided
|
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
|
return torrents, count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SearchParam struct {
|
type SearchParam struct {
|
||||||
|
@ -19,17 +21,6 @@ type SearchParam struct {
|
||||||
Sort string
|
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) {
|
func SearchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents, int) {
|
||||||
maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
|
maxPerPage, errConv := strconv.Atoi(r.URL.Query().Get("max"))
|
||||||
if errConv != nil {
|
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)
|
parameters.Params = append(parameters.Params, search_param.Status)
|
||||||
}
|
}
|
||||||
searchQuerySplit := strings.Split(search_param.Query, " ")
|
searchQuerySplit := strings.Fields(search_param.Query)
|
||||||
for i, _ := range searchQuerySplit {
|
for i, word := range searchQuerySplit {
|
||||||
conditions = append(conditions, "torrent_name " + search_op + " ?")
|
firstRune, _ := utf8.DecodeRuneInString(word)
|
||||||
parameters.Params = append(parameters.Params, "%"+searchQuerySplit[i]+"%")
|
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 ")
|
parameters.Conditions = strings.Join(conditions[:], " AND ")
|
||||||
|
|
Référencer dans un nouveau ticket