1
0

Update xorm to v1 (#323)

Fix limit for databases other than sqlite

go mod tidy && go mod vendor

Remove unneeded break statements

Make everything work with the new xorm version

Fix xorm logging

Fix lint

Fix redis init

Fix using id field

Fix database init for testing

Change default database log level

Add xorm logger

Use const for postgres

go mod tidy

Merge branch 'master' into update/xorm

# Conflicts:
#	go.mod
#	go.sum
#	vendor/modules.txt

go mod vendor

Fix loading fixtures for postgres

Go mod vendor1

Update xorm to version 1

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/323
This commit is contained in:
konrad
2020-04-12 17:29:24 +00:00
parent 713560702b
commit d28f005552
430 changed files with 48291 additions and 99915 deletions

View File

@ -78,13 +78,14 @@ const (
RedisPassword Key = `redis.password`
RedisDB Key = `redis.db`
LogEnabled Key = `log.enabled`
LogErrors Key = `log.errors`
LogStandard Key = `log.standard`
LogDatabase Key = `log.database`
LogHTTP Key = `log.http`
LogEcho Key = `log.echo`
LogPath Key = `log.path`
LogEnabled Key = `log.enabled`
LogErrors Key = `log.errors`
LogStandard Key = `log.standard`
LogDatabase Key = `log.database`
LogDatabaseLevel Key = `log.databaselevel`
LogHTTP Key = `log.http`
LogEcho Key = `log.echo`
LogPath Key = `log.path`
RateLimitEnabled Key = `ratelimit.enabled`
RateLimitKind Key = `ratelimit.kind`
@ -214,6 +215,7 @@ func InitDefaultConfig() {
LogErrors.setDefault("stdout")
LogStandard.setDefault("stdout")
LogDatabase.setDefault("off")
LogDatabaseLevel.setDefault("DEBUG")
LogHTTP.setDefault("stdout")
LogEcho.setDefault("off")
LogPath.setDefault(ServiceRootpath.GetString() + "/logs")

View File

@ -21,14 +21,14 @@ import (
"code.vikunja.io/api/pkg/log"
"encoding/gob"
"fmt"
xrc "gitea.com/xorm/xorm-redis-cache"
"net/url"
"strconv"
"strings"
"time"
"xorm.io/core"
"xorm.io/xorm"
xrc "gitea.com/xorm/xorm-redis-cache"
"xorm.io/xorm/caches"
_ "github.com/go-sql-driver/mysql" // Because.
_ "github.com/lib/pq" // Because.
@ -70,8 +70,7 @@ func CreateDBEngine() (engine *xorm.Engine, err error) {
}
engine.SetMapper(core.GonicMapper{})
logger := xorm.NewSimpleLogger(log.GetLogWriter("database"))
logger.ShowSQL(config.LogDatabase.GetString() != "off")
logger := log.NewXormLogger()
engine.SetLogger(logger)
// Cache
@ -79,10 +78,10 @@ func CreateDBEngine() (engine *xorm.Engine, err error) {
if config.CacheEnabled.GetBool() {
switch config.CacheType.GetString() {
case "memory":
cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), config.CacheMaxElementSize.GetInt())
cacher := caches.NewLRUCacher(caches.NewMemoryStore(), config.CacheMaxElementSize.GetInt())
engine.SetDefaultCacher(cacher)
case "redis":
cacher := xrc.NewRedisCacher(config.RedisEnabled.GetString(), config.RedisPassword.GetString(), xrc.DEFAULT_EXPIRATION, engine.Logger())
cacher := xrc.NewRedisCacher(config.RedisEnabled.GetString(), config.RedisPassword.GetString(), xrc.DEFAULT_EXPIRATION, log.GetXormLoggerForRedis(logger))
engine.SetDefaultCacher(cacher)
default:
log.Info("Did not find a valid cache type. Caching disabled. Please refer to the docs for poosible cache types.")

View File

@ -1,6 +1,7 @@
- id: 1
text: 'task #1'
description: 'Lorem Ipsum'
done: false
created_by_id: 1
list_id: 1
index: 1
@ -16,6 +17,7 @@
updated: 1543626724
- id: 3
text: 'task #3 high prio'
done: false
created_by_id: 1
list_id: 1
index: 3
@ -24,6 +26,7 @@
priority: 100
- id: 4
text: 'task #4 low prio'
done: false
created_by_id: 1
list_id: 1
index: 4
@ -32,6 +35,7 @@
priority: 1
- id: 5
text: 'task #5 higher due date'
done: false
created_by_id: 1
list_id: 1
index: 5
@ -40,6 +44,7 @@
due_date_unix: 1543636724
- id: 6
text: 'task #6 lower due date'
done: false
created_by_id: 1
list_id: 1
index: 6
@ -48,6 +53,7 @@
due_date_unix: 1543616724
- id: 7
text: 'task #7 with start date'
done: false
created_by_id: 1
list_id: 1
index: 7
@ -56,6 +62,7 @@
start_date_unix: 1544600000
- id: 8
text: 'task #8 with end date'
done: false
created_by_id: 1
list_id: 1
index: 8
@ -64,6 +71,7 @@
end_date_unix: 1544700000
- id: 9
text: 'task #9 with start and end date'
done: false
created_by_id: 1
list_id: 1
index: 9
@ -73,6 +81,7 @@
end_date_unix: 1544700000
- id: 10
text: 'task #10 basic'
done: false
created_by_id: 1
list_id: 1
index: 10
@ -80,6 +89,7 @@
updated: 1543626724
- id: 11
text: 'task #11 basic'
done: false
created_by_id: 1
list_id: 1
index: 11
@ -87,6 +97,7 @@
updated: 1543626724
- id: 12
text: 'task #12 basic'
done: false
created_by_id: 1
list_id: 1
index: 12
@ -94,6 +105,7 @@
updated: 1543626724
- id: 13
text: 'task #13 basic other list'
done: false
created_by_id: 1
list_id: 2
index: 1
@ -101,6 +113,7 @@
updated: 1543626724
- id: 14
text: 'task #14 basic other list'
done: false
created_by_id: 5
list_id: 5
index: 1
@ -108,6 +121,7 @@
updated: 1543626724
- id: 15
text: 'task #15'
done: false
created_by_id: 6
list_id: 6
index: 1
@ -115,6 +129,7 @@
updated: 1543626724
- id: 16
text: 'task #16'
done: false
created_by_id: 6
list_id: 7
index: 1
@ -122,6 +137,7 @@
updated: 1543626724
- id: 17
text: 'task #17'
done: false
created_by_id: 6
list_id: 8
index: 1
@ -129,6 +145,7 @@
updated: 1543626724
- id: 18
text: 'task #18'
done: false
created_by_id: 6
list_id: 9
index: 1
@ -136,6 +153,7 @@
updated: 1543626724
- id: 19
text: 'task #19'
done: false
created_by_id: 6
list_id: 10
index: 1
@ -143,6 +161,7 @@
updated: 1543626724
- id: 20
text: 'task #20'
done: false
created_by_id: 6
list_id: 11
index: 1
@ -150,6 +169,7 @@
updated: 1543626724
- id: 21
text: 'task #21'
done: false
created_by_id: 6
list_id: 12
index: 1
@ -157,6 +177,7 @@
updated: 1543626724
- id: 22
text: 'task #22'
done: false
created_by_id: 6
list_id: 13
index: 1
@ -164,6 +185,7 @@
updated: 1543626724
- id: 23
text: 'task #23'
done: false
created_by_id: 6
list_id: 14
index: 1
@ -171,6 +193,7 @@
updated: 1543626724
- id: 24
text: 'task #24'
done: false
created_by_id: 6
list_id: 15
index: 1
@ -178,6 +201,7 @@
updated: 1543626724
- id: 25
text: 'task #25'
done: false
created_by_id: 6
list_id: 16
index: 1
@ -185,6 +209,7 @@
updated: 1543626724
- id: 26
text: 'task #26'
done: false
created_by_id: 6
list_id: 17
index: 1
@ -192,6 +217,7 @@
updated: 1543626724
- id: 27
text: 'task #27 with reminders'
done: false
created_by_id: 1
list_id: 1
index: 12
@ -208,6 +234,7 @@
updated: 1543626724
- id: 29
text: 'task #29 with parent task (1)'
done: false
created_by_id: 1
list_id: 1
index: 14
@ -215,6 +242,7 @@
updated: 1543626724
- id: 30
text: 'task #30 with assignees'
done: false
created_by_id: 1
list_id: 1
index: 15
@ -222,6 +250,7 @@
updated: 1543626724
- id: 31
text: 'task #31 with color'
done: false
created_by_id: 1
list_id: 1
index: 16
@ -230,6 +259,7 @@
updated: 1543626724
- id: 32
text: 'task #32'
done: false
created_by_id: 1
list_id: 3
index: 1
@ -237,6 +267,7 @@
updated: 1543626724
- id: 33
text: 'task #33 with percent done'
done: false
created_by_id: 1
list_id: 1
index: 17
@ -246,6 +277,7 @@
# This task is forbidden for user1
- id: 34
text: 'task #34'
done: false
created_by_id: 13
list_id: 20
index: 20
@ -253,6 +285,7 @@
updated: 1543626724
- id: 35
text: 'task #35'
done: false
created_by_id: 1
list_id: 21
index: 1
@ -260,6 +293,7 @@
updated: 1543626724
- id: 36
text: 'task #36'
done: false
created_by_id: 1
list_id: 22
index: 1

View File

@ -46,7 +46,7 @@ func CreateTestEngine() (engine *xorm.Engine, err error) {
}
engine.SetMapper(core.GonicMapper{})
logger := xorm.NewSimpleLogger(log.GetLogWriter("database"))
logger := log.NewXormLogger()
logger.ShowSQL(os.Getenv("UNIT_TESTS_VERBOSE") == "1")
engine.SetLogger(logger)
x = engine

View File

@ -24,6 +24,7 @@ import (
"github.com/stretchr/testify/assert"
"path/filepath"
"testing"
"xorm.io/xorm/schemas"
)
var fixtures *testfixtures.Loader
@ -73,7 +74,7 @@ func LoadFixtures() error {
// Copied from https://github.com/go-gitea/gitea/blob/master/models/test_fixtures.go#L39
// Now if we're running postgres we need to tell it to update the sequences
if x.Dialect().DriverName() == "postgres" {
if x.Dialect().URI().DBType == schemas.POSTGRES {
results, err := x.QueryString(`SELECT 'SELECT SETVAL(' ||
quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||

188
pkg/log/xorm_logger.go Normal file
View File

@ -0,0 +1,188 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package log
import (
"code.vikunja.io/api/pkg/config"
"github.com/op/go-logging"
"time"
"xorm.io/core"
"xorm.io/xorm/log"
)
// XormFmt defines the format for xorm logging strings
const XormFmt = `%{color}%{time:` + time.RFC3339Nano + `}: %{level}` + "\t" + `▶ [DATABASE] %{id:03x}%{color:reset} %{message}`
const xormLogModule = `vikunja_database`
// XormLogger holds an implementation of the xorm logger interface.
type XormLogger struct {
logger *logging.Logger
level log.LogLevel
showSQL bool
}
// NewXormLogger creates and initializes a new xorm logger
func NewXormLogger() *XormLogger {
level, err := logging.LogLevel(config.LogDatabaseLevel.GetString())
if err != nil {
Critical("Error setting database log level: %s", err.Error())
}
xormLogger := &XormLogger{
logger: logging.MustGetLogger(xormLogModule),
}
logBackend := logging.NewLogBackend(GetLogWriter("database"), "", 0)
backend := logging.NewBackendFormatter(logBackend, logging.MustStringFormatter(XormFmt+"\n"))
backendLeveled := logging.AddModuleLevel(backend)
backendLeveled.SetLevel(level, xormLogModule)
xormLogger.logger.SetBackend(backendLeveled)
switch level {
case logging.CRITICAL:
case logging.ERROR:
xormLogger.level = log.LOG_ERR
case logging.WARNING:
case logging.NOTICE:
xormLogger.level = log.LOG_WARNING
case logging.INFO:
xormLogger.level = log.LOG_INFO
case logging.DEBUG:
xormLogger.level = log.LOG_DEBUG
default:
xormLogger.level = log.LOG_OFF
}
xormLogger.showSQL = true
return xormLogger
}
// Debug logs a debug string
func (x *XormLogger) Debug(v ...interface{}) {
x.logger.Debug(v...)
}
// Debugf logs a debug string
func (x *XormLogger) Debugf(format string, v ...interface{}) {
x.logger.Debugf(format, v...)
}
// Error logs a debug string
func (x *XormLogger) Error(v ...interface{}) {
x.logger.Error(v...)
}
// Errorf logs a debug string
func (x *XormLogger) Errorf(format string, v ...interface{}) {
x.logger.Errorf(format, v...)
}
// Info logs an info string
func (x *XormLogger) Info(v ...interface{}) {
x.logger.Info(v...)
}
// Infof logs an info string
func (x *XormLogger) Infof(format string, v ...interface{}) {
x.logger.Infof(format, v...)
}
// Warn logs a warning string
func (x *XormLogger) Warn(v ...interface{}) {
x.logger.Warning(v...)
}
// Warnf logs a warning string
func (x *XormLogger) Warnf(format string, v ...interface{}) {
x.logger.Warningf(format, v...)
}
// Level returns the current set log level
func (x *XormLogger) Level() log.LogLevel {
return x.level
}
// SetLevel sets the log level
func (x *XormLogger) SetLevel(l log.LogLevel) {
x.level = l
}
// ShowSQL sets whether to show the log level or not
func (x *XormLogger) ShowSQL(show ...bool) {
if len(show) > 0 {
x.showSQL = show[0]
}
}
// IsShowSQL returns if sql queries should be shown
func (x *XormLogger) IsShowSQL() bool {
return x.showSQL
}
// XormRedisCacherLogger is used as a compatibility layer to be able to re-use the same logger from xorm until
// the redis cacher module accepts the same logger.
// See https://gitea.com/xorm/xorm-redis-cache/issues/10
type XormRedisCacherLogger struct {
XormLogger
}
// GetXormLoggerForRedis creates a new xorm logger which can be used with redis
func GetXormLoggerForRedis(x *XormLogger) *XormRedisCacherLogger {
return &XormRedisCacherLogger{*x}
}
// Level returns the currently set log level
func (x *XormRedisCacherLogger) Level() core.LogLevel {
switch x.level {
case log.LOG_DEBUG:
return core.LOG_DEBUG
case log.LOG_INFO:
return core.LOG_INFO
case log.LOG_WARNING:
return core.LOG_WARNING
case log.LOG_ERR:
return core.LOG_ERR
case log.LOG_OFF:
return core.LOG_OFF
case log.LOG_UNKNOWN:
return core.LOG_UNKNOWN
default:
return core.LOG_UNKNOWN
}
}
// SetLevel sets the log level
func (x *XormRedisCacherLogger) SetLevel(l core.LogLevel) {
switch l {
case core.LOG_DEBUG:
x.level = log.LOG_DEBUG
case core.LOG_INFO:
x.level = log.LOG_INFO
case core.LOG_WARNING:
x.level = log.LOG_WARNING
case core.LOG_ERR:
x.level = log.LOG_ERR
case core.LOG_OFF:
x.level = log.LOG_OFF
default:
x.level = log.LOG_UNKNOWN
}
}

View File

@ -20,7 +20,7 @@ import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/red"
"github.com/go-redis/redis"
"github.com/go-redis/redis/v7"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

View File

@ -60,7 +60,7 @@ func init() {
// Get all current subtasks and put them in a new table
tasks := []*task20190922205826{}
err = tx.Where("parent_task_id != null OR parent_task_id != 0").Find(&tasks)
err = tx.Where("parent_task_id is not null OR parent_task_id != 0").Find(&tasks)
if err != nil {
return err
}

View File

@ -76,7 +76,7 @@ func (l *Label) hasAccessToLabel(a web.Auth) (bool, error) {
has, err := x.Table("labels").
Select("labels.*").
Join("LEFT", "label_task", "label_task.label_id = labels.id").
Where("label_task.label_id != null OR labels.created_by_id = ?", a.GetID()).
Where("label_task.label_id is not null OR labels.created_by_id = ?", a.GetID()).
Or(builder.In("label_task.task_id", taskIDs)).
And("labels.id = ?", l.ID).
Exist(&labels)

View File

@ -162,20 +162,27 @@ func getLabelsByTaskIDs(opts *LabelByTaskIDsOptions) (ls []*labelWithTaskID, res
// Get all labels associated with these tasks
var labels []*labelWithTaskID
cond := builder.And(builder.In("label_task.task_id", opts.TaskIDs), builder.NotNull{"label_task.label_id"})
cond := builder.And(builder.NotNull{"label_task.label_id"})
if len(opts.TaskIDs) > 0 {
cond = builder.And(builder.In("label_task.task_id", opts.TaskIDs), cond)
}
if opts.GetUnusedLabels {
cond = builder.Or(cond, builder.Eq{"labels.created_by_id": opts.User.ID})
}
err = x.Table("labels").
limit, start := getLimitFromPageIndex(opts.Page, opts.PerPage)
query := x.Table("labels").
Select(selectStmt).
Join("LEFT", "label_task", "label_task.label_id = labels.id").
Where(cond).
And("labels.title LIKE ?", "%"+opts.Search+"%").
GroupBy(groupBy).
OrderBy("labels.id ASC").
Limit(getLimitFromPageIndex(opts.Page, opts.PerPage)).
Find(&labels)
OrderBy("labels.id ASC")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&labels)
if err != nil {
return nil, 0, 0, err
}

View File

@ -155,11 +155,15 @@ func (share *LinkSharing) ReadAll(a web.Auth, search string, page int, perPage i
return nil, 0, 0, ErrGenericForbidden{}
}
limit, start := getLimitFromPageIndex(page, perPage)
var shares []*LinkSharing
err = x.
Where("list_id = ? AND hash LIKE ?", share.ListID, "%"+search+"%").
Limit(getLimitFromPageIndex(page, perPage)).
Find(&shares)
query := x.
Where("list_id = ? AND hash LIKE ?", share.ListID, "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&shares)
if err != nil {
return nil, 0, 0, err
}

View File

@ -235,9 +235,11 @@ func getRawListsForUser(opts *listOptions) (lists []*List, resultCount int, tota
)
}
limit, start := getLimitFromPageIndex(opts.page, opts.perPage)
// Gets all Lists where the user is either owner or in a team which has access to the list
// Or in a team which has namespace read access
err = x.Select("l.*").
query := x.Select("l.*").
Table("list").
Alias("l").
Join("INNER", []string{"namespaces", "n"}, "l.namespace_id = n.id").
@ -247,16 +249,20 @@ func getRawListsForUser(opts *listOptions) (lists []*List, resultCount int, tota
Join("LEFT", []string{"team_members", "tm2"}, "tm2.team_id = tl.team_id").
Join("LEFT", []string{"users_list", "ul"}, "ul.list_id = l.id").
Join("LEFT", []string{"users_namespace", "un"}, "un.namespace_id = l.namespace_id").
Where("tm.user_id = ?", fullUser.ID).
Or("tm2.user_id = ?", fullUser.ID).
Or("l.owner_id = ?", fullUser.ID).
Or("ul.user_id = ?", fullUser.ID).
Or("un.user_id = ?", fullUser.ID).
Where(builder.Or(
builder.Eq{"tm.user_id": fullUser.ID},
builder.Eq{"tm2.user_id": fullUser.ID},
builder.Eq{"ul.user_id": fullUser.ID},
builder.Eq{"un.user_id": fullUser.ID},
builder.Eq{"l.owner_id": fullUser.ID},
)).
GroupBy("l.id").
Limit(getLimitFromPageIndex(opts.page, opts.perPage)).
Where("l.title LIKE ?", "%"+opts.search+"%").
Where(isArchivedCond).
Find(&lists)
Where(isArchivedCond)
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&lists)
if err != nil {
return nil, 0, 0, err
}
@ -271,13 +277,14 @@ func getRawListsForUser(opts *listOptions) (lists []*List, resultCount int, tota
Join("LEFT", []string{"team_members", "tm2"}, "tm2.team_id = tl.team_id").
Join("LEFT", []string{"users_list", "ul"}, "ul.list_id = l.id").
Join("LEFT", []string{"users_namespace", "un"}, "un.namespace_id = l.namespace_id").
Where("tm.user_id = ?", fullUser.ID).
Or("tm2.user_id = ?", fullUser.ID).
Or("l.owner_id = ?", fullUser.ID).
Or("ul.user_id = ?", fullUser.ID).
Or("un.user_id = ?", fullUser.ID).
Where(builder.Or(
builder.Eq{"tm.user_id": fullUser.ID},
builder.Eq{"tm2.user_id": fullUser.ID},
builder.Eq{"ul.user_id": fullUser.ID},
builder.Eq{"un.user_id": fullUser.ID},
builder.Eq{"l.owner_id": fullUser.ID},
)).
GroupBy("l.id").
Limit(getLimitFromPageIndex(opts.page, opts.perPage)).
Where("l.title LIKE ?", "%"+opts.search+"%").
Where(isArchivedCond).
Count(&List{})

View File

@ -176,15 +176,19 @@ func (tl *TeamList) ReadAll(a web.Auth, search string, page int, perPage int) (r
return nil, 0, 0, ErrNeedToHaveListReadAccess{ListID: tl.ListID, UserID: a.GetID()}
}
limit, start := getLimitFromPageIndex(page, perPage)
// Get the teams
all := []*TeamWithRight{}
err = x.
query := x.
Table("teams").
Join("INNER", "team_list", "team_id = teams.id").
Where("team_list.list_id = ?", tl.ListID).
Limit(getLimitFromPageIndex(page, perPage)).
Where("teams.name LIKE ?", "%"+search+"%").
Find(&all)
Where("teams.name LIKE ?", "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&all)
if err != nil {
return nil, 0, 0, err
}

View File

@ -182,14 +182,18 @@ func (lu *ListUser) ReadAll(a web.Auth, search string, page int, perPage int) (r
return nil, 0, 0, ErrNeedToHaveListReadAccess{UserID: a.GetID(), ListID: lu.ListID}
}
limit, start := getLimitFromPageIndex(page, perPage)
// Get all users
all := []*UserWithRight{}
err = x.
query := x.
Join("INNER", "users_list", "user_id = users.id").
Where("users_list.list_id = ?", lu.ListID).
Limit(getLimitFromPageIndex(page, perPage)).
Where("users.username LIKE ?", "%"+search+"%").
Find(&all)
Where("users.username LIKE ?", "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&all)
if err != nil {
return nil, 0, 0, err
}

View File

@ -72,8 +72,8 @@ func SetEngine() (err error) {
func getLimitFromPageIndex(page int, perPage int) (limit, start int) {
// Get everything when page index is -1
if page < 0 {
// Get everything when page index is -1 or 0 (= not set)
if page < 1 {
return 0, 0
}

View File

@ -190,7 +190,9 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
[]*List{},
})
err = x.Select("namespaces.*").
limit, start := getLimitFromPageIndex(page, perPage)
query := x.Select("namespaces.*").
Table("namespaces").
Join("LEFT", "team_namespaces", "namespaces.id = team_namespaces.namespace_id").
Join("LEFT", "team_members", "team_members.team_id = team_namespaces.team_id").
@ -199,10 +201,12 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
Or("namespaces.owner_id = ?", doer.ID).
Or("users_namespace.user_id = ?", doer.ID).
GroupBy("namespaces.id").
Limit(getLimitFromPageIndex(page, perPage)).
Where("namespaces.name LIKE ?", "%"+search+"%").
Where(isArchivedCond).
Find(&all)
Where(isArchivedCond)
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&all)
if err != nil {
return all, 0, 0, err
}

View File

@ -164,12 +164,16 @@ func (tn *TeamNamespace) ReadAll(a web.Auth, search string, page int, perPage in
// Get the teams
all := []*TeamWithRight{}
err = x.Table("teams").
limit, start := getLimitFromPageIndex(page, perPage)
query := x.Table("teams").
Join("INNER", "team_namespaces", "team_id = teams.id").
Where("team_namespaces.namespace_id = ?", tn.NamespaceID).
Limit(getLimitFromPageIndex(page, perPage)).
Where("teams.name LIKE ?", "%"+search+"%").
Find(&all)
Where("teams.name LIKE ?", "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&all)
if err != nil {
return nil, 0, 0, err
}

View File

@ -170,12 +170,17 @@ func (nu *NamespaceUser) ReadAll(a web.Auth, search string, page int, perPage in
// Get all users
all := []*UserWithRight{}
err = x.
limit, start := getLimitFromPageIndex(page, perPage)
query := x.
Join("INNER", "users_namespace", "user_id = users.id").
Where("users_namespace.namespace_id = ?", nu.NamespaceID).
Limit(getLimitFromPageIndex(page, perPage)).
Where("users.username LIKE ?", "%"+search+"%").
Find(&all)
Where("users.username LIKE ?", "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&all)
if err != nil {
return nil, 0, 0, err
}

View File

@ -253,14 +253,17 @@ func (la *TaskAssginee) ReadAll(a web.Auth, search string, page int, perPage int
if !can {
return nil, 0, 0, ErrGenericForbidden{}
}
limit, start := getLimitFromPageIndex(page, perPage)
var taskAssignees []*user.User
err = x.Table("task_assignees").
query := x.Table("task_assignees").
Select("users.*").
Join("INNER", "users", "task_assignees.user_id = users.id").
Where("task_id = ? AND users.username LIKE ?", la.TaskID, "%"+search+"%").
Limit(getLimitFromPageIndex(page, perPage)).
Find(&taskAssignees)
Where("task_id = ? AND users.username LIKE ?", la.TaskID, "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&taskAssignees)
if err != nil {
return nil, 0, 0, err
}

View File

@ -112,10 +112,14 @@ func (ta *TaskAttachment) ReadOne() (err error) {
func (ta *TaskAttachment) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
attachments := []*TaskAttachment{}
err = x.
Limit(getLimitFromPageIndex(page, perPage)).
Where("task_id = ?", ta.TaskID).
Find(&attachments)
limit, start := getLimitFromPageIndex(page, perPage)
query := x.
Where("task_id = ?", ta.TaskID)
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&attachments)
if err != nil {
return nil, 0, 0, err
}

View File

@ -180,12 +180,16 @@ func (tc *TaskComment) ReadAll(auth web.Auth, search string, page int, perPage i
AuthorFromDB *user.User `xorm:"extends" json:"-"`
}
limit, start := getLimitFromPageIndex(page, perPage)
comments := []*TaskComment{}
err = x.
query := x.
Where("task_id = ? AND comment like ?", tc.TaskID, "%"+search+"%").
Join("LEFT", "users", "users.id = task_comments.author_id").
Limit(getLimitFromPageIndex(page, perPage)).
Find(&comments)
Join("LEFT", "users", "users.id = task_comments.author_id")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&comments)
if err != nil {
return
}

View File

@ -39,7 +39,7 @@ type Task struct {
// The task description.
Description string `xorm:"longtext null" json:"description"`
// Whether a task is done or not.
Done bool `xorm:"INDEX null default false" json:"done"`
Done bool `xorm:"INDEX null" json:"done"`
// The time when a task was marked as done.
DoneAt timeutil.TimeStamp `xorm:"INDEX null 'done_at_unix'" json:"doneAt"`
// The time when the task is due.
@ -184,41 +184,38 @@ func getRawTasksForLists(lists []*List, opts *taskOptions) (taskMap map[int64]*T
taskMap = make(map[int64]*Task)
// Then return all tasks for that lists
if len(filters) > 0 {
query := x.
OrderBy(orderby)
err := x.In("list_id", listIDs).
Where("text LIKE ?", "%"+opts.search+"%").
Where(builder.Or(filters...)).
OrderBy(orderby).
Limit(getLimitFromPageIndex(opts.page, opts.perPage)).
Find(&taskMap)
if err != nil {
return nil, 0, 0, err
}
totalItems, err = x.In("list_id", listIDs).
Where("text LIKE ?", "%"+opts.search+"%").
Where(builder.Or(filters...)).
Count(&Task{})
if err != nil {
return nil, 0, 0, err
}
} else {
err := x.In("list_id", listIDs).
Where("text LIKE ?", "%"+opts.search+"%").
OrderBy(orderby).
Limit(getLimitFromPageIndex(opts.page, opts.perPage)).
Find(&taskMap)
if err != nil {
return nil, 0, 0, err
}
totalItems, err = x.In("list_id", listIDs).
Where("text LIKE ?", "%"+opts.search+"%").
Count(&Task{})
if err != nil {
return nil, 0, 0, err
}
if len(opts.search) > 0 {
query = query.Where("text LIKE ?", "%"+opts.search+"%")
}
if len(listIDs) > 0 {
query = query.In("list_id", listIDs)
}
if len(filters) > 0 {
query = query.Where(builder.Or(filters...))
}
limit, start := getLimitFromPageIndex(opts.page, opts.perPage)
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&taskMap)
if err != nil {
return nil, 0, 0, err
}
totalItems, err = query.
Count(&Task{})
if err != nil {
return nil, 0, 0, err
}
return taskMap, len(taskMap), totalItems, nil
}

View File

@ -203,14 +203,18 @@ func (t *Team) ReadAll(a web.Auth, search string, page int, perPage int) (result
return nil, 0, 0, ErrGenericForbidden{}
}
limit, start := getLimitFromPageIndex(page, perPage)
all := []*Team{}
err = x.Select("teams.*").
query := x.Select("teams.*").
Table("teams").
Join("INNER", "team_members", "team_members.team_id = teams.id").
Where("team_members.user_id = ?", a.GetID()).
Limit(getLimitFromPageIndex(page, perPage)).
Where("teams.name LIKE ?", "%"+search+"%").
Find(&all)
Where("teams.name LIKE ?", "%"+search+"%")
if limit > 0 {
query = query.Limit(limit, start)
}
err = query.Find(&all)
if err != nil {
return nil, 0, 0, err
}

View File

@ -19,7 +19,7 @@ package red
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"github.com/go-redis/redis"
"github.com/go-redis/redis/v7"
)
var r *redis.Client

View File

@ -309,7 +309,7 @@ func UpdateUser(user *User) (updatedUser *User, err error) {
user.Password = theUser.Password // set the password to the one in the database to not accedently resetting it
// Update it
_, err = x.Id(user.ID).Update(user)
_, err = x.ID(user.ID).Update(user)
if err != nil {
return &User{}, err
}
@ -344,7 +344,7 @@ func UpdateUserPassword(user *User, newPassword string) (err error) {
theUser.Password = hashed
// Update it
_, err = x.Id(user.ID).Update(theUser)
_, err = x.ID(user.ID).Update(theUser)
if err != nil {
return err
}