diff --git a/go.mod b/go.mod index 23e922ecef2df..10c3f192db763 100644 --- a/go.mod +++ b/go.mod @@ -98,7 +98,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 mvdan.cc/xurls/v2 v2.4.0 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 - xorm.io/builder v0.3.10 + xorm.io/builder v0.3.11-0.20220528023925-443794ecabe6 xorm.io/xorm v1.2.5 ) diff --git a/go.sum b/go.sum index 3af17c070b0fa..dd9cdc1f26780 100644 --- a/go.sum +++ b/go.sum @@ -2319,7 +2319,7 @@ sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3FJbP5Cvdq7Khzn6J9OCUQJaBwgBkCR+MOwSs= strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY= xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= -xorm.io/builder v0.3.10 h1:Rvkncad3Lo9YIVqCbgIf6QnpR/HcW3IEr0AANNpuyMQ= -xorm.io/builder v0.3.10/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= +xorm.io/builder v0.3.11-0.20220528023925-443794ecabe6 h1:q87Pe12cfWbN7gCS2dydxNQwr4V29EQjyP+LhsBQ0QQ= +xorm.io/builder v0.3.11-0.20220528023925-443794ecabe6/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= xorm.io/xorm v1.2.5 h1:tqN7OhN8P9xi52qBb76I8m5maAJMz/SSbgK2RGPCPbo= xorm.io/xorm v1.2.5/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0= diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 8f08da16a107a..003bc46bd9747 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -109,6 +109,11 @@ func TestAPISearchRepo(t *testing.T) { user2: {count: 7, repoName: "big_test_"}, }, }, + { + name: "RepositoriesByName", requestURL: fmt.Sprintf("/api/v1/repos/search?q=%s&private=false", "user2/big_test_"), expectedResults: expectedResults{ + user2: {count: 7, repoName: "big_test_"}, + }, + }, { name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{ nil: {count: 5}, diff --git a/models/repo_list.go b/models/repo_list.go index 906b7548d4a64..61ce736529c9c 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -520,7 +521,8 @@ func SearchRepository(opts *SearchRepoOptions) (RepositoryList, int64, error) { // SearchRepositoryByCondition search repositories by condition func SearchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond, loadAttributes bool) (RepositoryList, int64, error) { ctx := db.DefaultContext - sess, count, err := searchRepositoryByCondition(ctx, opts, cond) + + b, count, err := searchRepositoryByCondition(ctx, opts, "*", cond) if err != nil { return nil, 0, err } @@ -530,7 +532,7 @@ func SearchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond, loa defaultSize = opts.PageSize } repos := make(RepositoryList, 0, defaultSize) - if err := sess.Find(&repos); err != nil { + if err := db.GetEngine(ctx).SQL(b).Find(&repos); err != nil { return nil, 0, fmt.Errorf("Repo: %v", err) } @@ -547,41 +549,57 @@ func SearchRepositoryByCondition(opts *SearchRepoOptions, cond builder.Cond, loa return repos, count, nil } -func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, cond builder.Cond) (db.Engine, int64, error) { +func withDB() *builder.Builder { + switch { + case setting.Database.UseSQLite3: + return builder.Dialect(builder.SQLITE) + case setting.Database.UseMySQL: + return builder.Dialect(builder.MYSQL) + case setting.Database.UsePostgreSQL: + return builder.Dialect(builder.POSTGRES) + case setting.Database.UseMSSQL: + return builder.Dialect(builder.MSSQL) + } + return &builder.Builder{} +} + +func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, selCols string, cond builder.Cond) (*builder.Builder, int64, error) { if opts.Page <= 0 { opts.Page = 1 } + var count int64 + if opts.PageSize > 0 { + var err error + count, err = db.GetEngine(ctx). + Where(cond). + Count(new(repo_model.Repository)) + if err != nil { + return nil, 0, fmt.Errorf("Count: %v", err) + } + } + if len(opts.OrderBy) == 0 { opts.OrderBy = db.SearchOrderByAlphabetically } + var orderBy interface{} if opts.PriorityOwnerID > 0 { - opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_id = %d THEN 0 ELSE owner_id END, %s", opts.PriorityOwnerID, opts.OrderBy)) + orderBy = fmt.Sprintf("CASE WHEN owner_id = %d THEN 0 ELSE owner_id END, %s", opts.PriorityOwnerID, opts.OrderBy) } else if strings.Count(opts.Keyword, "/") == 1 { // With "owner/repo" search times, prioritise results which match the owner field orgName := strings.Split(opts.Keyword, "/")[0] - opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_name LIKE '%s' THEN 0 ELSE 1 END, %s", orgName, opts.OrderBy)) + orderBy = builder.Expr(fmt.Sprintf("CASE WHEN owner_name LIKE ? THEN 0 ELSE 1 END, %s", opts.OrderBy), orgName) + } else { + orderBy = opts.OrderBy.String() } - sess := db.GetEngine(ctx) - - var count int64 + b := withDB().Select(selCols).From("repository").Where(cond).OrderBy(orderBy) if opts.PageSize > 0 { - var err error - count, err = sess. - Where(cond). - Count(new(repo_model.Repository)) - if err != nil { - return nil, 0, fmt.Errorf("Count: %v", err) - } + b.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) } - sess = sess.Where(cond).OrderBy(opts.OrderBy.String()) - if opts.PageSize > 0 { - sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) - } - return sess, count, nil + return b, count, nil } // accessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible @@ -634,7 +652,7 @@ func SearchRepositoryIDs(opts *SearchRepoOptions) ([]int64, int64, error) { cond := SearchRepositoryCondition(opts) - sess, count, err := searchRepositoryByCondition(db.DefaultContext, opts, cond) + b, count, err := searchRepositoryByCondition(db.DefaultContext, opts, "id", cond) if err != nil { return nil, 0, err } @@ -645,7 +663,7 @@ func SearchRepositoryIDs(opts *SearchRepoOptions) ([]int64, int64, error) { } ids := make([]int64, 0, defaultSize) - err = sess.Select("id").Table("repository").Find(&ids) + err = db.GetEngine(db.DefaultContext).SQL(b).Find(&ids) if opts.PageSize <= 0 { count = int64(len(ids)) }