// Copyright 2016 The Gogs Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models import ( "time" "fmt" "github.com/go-xorm/xorm" git "github.com/gogits/git-module" ) type Commit struct { ID int64 RepoID int64 `xorm:"UNIQUE(commit_repo_sha)"` Sha string `xorm:"VARCHAR(40) UNIQUE(commit_repo_sha)"` Message string `xorm:"TEXT FULLTEXT(commit_message)"` AuthorEmail string AuthorName string AuthorTime time.Time CommitterEmail string CommitterName string CommitterTime time.Time Repo *Repository `xorm:"-"` } func GitCommitToSearchCommit(repoID int64, commit *git.Commit) *Commit { return &Commit{ RepoID: repoID, Sha: commit.ID.String(), Message: commit.Message(), AuthorEmail: commit.Author.Email, AuthorName: commit.Author.Name, AuthorTime: commit.Author.When, CommitterEmail: commit.Committer.Email, CommitterName: commit.Committer.Name, CommitterTime: commit.Committer.When, } } func FulltextSearchCommits(userid int64, q string, limit int, offset int) ([]*Commit, int64, error) { sess := x.NewSession() sess.Join("INNER", "repository", "repository.id = commit.repo_id") if userid > 0 { sess.Join("LEFT", "access", "access.repo_id = commit.repo_id AND access.user_id=?", userid) sess.Where("(NOT repository.is_private OR access.user_id IS NOT NULL OR repository.owner_id=?)", userid) } else { sess.Where("NOT repository.is_private") } if q != "" { cond, params := x.FulltextMatch("message", q) sess.Where(cond, params...) } var countSess xorm.Session countSess = *sess count, err := countSess.Count(new(Commit)) if err != nil { return nil, 0, fmt.Errorf("Count: %v", err) } sess.OrderBy("commit.committer_time DESC") sess.Limit(limit, offset) commits := make([]*Commit, 0) if err := sess.Find(&commits); err != nil { return nil, 0, fmt.Errorf("Find: %v", err) } if len(commits) == 0 { return commits, count, nil } // Load repositories set := make(map[int64]*Repository) for i := range commits { set[commits[i].RepoID] = nil } ids := make([]int64, 0, len(set)) for i := range set { ids = append(ids, i) } repos := make([]*Repository, 0, len(ids)) if err := sess.In("id", ids).Find(&repos); err != nil { return nil, 0, fmt.Errorf("Find repos: %v", err) } if err = RepositoryList(repos).LoadAttributes(); err != nil { return nil, 0, fmt.Errorf("Load repo attrs: %v", err) } for i := range repos { set[repos[i].ID] = repos[i] } for i := range commits { commits[i].Repo = set[commits[i].RepoID] } return commits, count, nil }