@@ -3,13 +3,68 @@ package function
33import (
44 "fmt"
55 "github.com/src-d/gitbase"
6- "gopkg.in/src-d/go-git.v4"
76 "github.com/src-d/go-mysql-server/sql"
7+ "gopkg.in/src-d/go-git.v4"
88
99 "gopkg.in/src-d/go-git.v4/plumbing"
1010 "gopkg.in/src-d/go-git.v4/plumbing/object"
1111)
1212
13+ type BlameGenerator struct {
14+ commit * object.Commit
15+ fIter * object.FileIter
16+ curLine int
17+ curFile * object.File
18+ lines []* git.Line
19+ }
20+
21+ func NewBlameGenerator (c * object.Commit , f * object.FileIter ) (* BlameGenerator , error ) {
22+ return & BlameGenerator {commit : c , fIter : f , curLine : - 1 }, nil
23+ }
24+
25+ func (g * BlameGenerator ) loadNewFile () error {
26+ var err error
27+ g .curFile , err = g .fIter .Next ()
28+ if err != nil {
29+ return err
30+ }
31+
32+ result , err := git .Blame (g .commit , g .curFile .Name )
33+ if err != nil {
34+ return err
35+ }
36+ g .lines = result .Lines
37+ g .curLine = 0
38+ return nil
39+ }
40+
41+ func (g * BlameGenerator ) Next () (interface {}, error ) {
42+ if g .curLine == - 1 || g .curLine >= len (g .lines ) {
43+ err := g .loadNewFile ()
44+ if err != nil {
45+ return nil , err
46+ }
47+ }
48+
49+ l := g .lines [g .curLine ]
50+ b := BlameLine {
51+ Commit : g .commit .Hash .String (),
52+ File : g .curFile .Name ,
53+ LineNum : g .curLine ,
54+ Author : l .Author ,
55+ Text : l .Text ,
56+ }
57+ g .curLine ++
58+ return b , nil
59+ }
60+
61+ func (g * BlameGenerator ) Close () error {
62+ g .fIter .Close ()
63+ return nil
64+ }
65+
66+ var _ sql.Generator = (* BlameGenerator )(nil )
67+
1368type (
1469 // Blame implements git-blame function as UDF
1570 Blame struct {
@@ -83,27 +138,13 @@ func (b *Blame) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
83138 if err != nil {
84139 return nil , err
85140 }
86- defer fIter .Close ()
87141
88- var lines []BlameLine
89- for f , err := fIter .Next (); err == nil ; f , err = fIter .Next () {
90- result , err := git .Blame (commit , f .Name )
91- if err != nil {
92- return nil , err
93- }
94-
95- for i , l := range result .Lines {
96- lines = append (lines , BlameLine {
97- Commit : commit .Hash .String (),
98- File : f .Name ,
99- LineNum : i ,
100- Author : l .Author ,
101- Text : l .Text ,
102- })
103- }
142+ bg , err := NewBlameGenerator (commit , fIter )
143+ if err != nil {
144+ return nil , err
104145 }
105146
106- return lines , nil
147+ return bg , nil
107148}
108149
109150func (b * Blame ) resolveCommit (ctx * sql.Context , repo * gitbase.Repository , row sql.Row ) (* object.Commit , error ) {
0 commit comments