diff --git a/cmd/vet-bot/issues.go b/cmd/vet-bot/issues.go index 294421c..7a6fd8f 100644 --- a/cmd/vet-bot/issues.go +++ b/cmd/vet-bot/issues.go @@ -64,31 +64,30 @@ func (ir *IssueReporter) ReportVetResult(result VetResult) { } ir.md5s[md5Sum] = struct{}{} - // TODO: we can't make this non-blocking until proteus can return an sql.Result - // async usage here causes a race-condition in persistResult with last_insert_rowid() - /*ir.bot.wg.Add(1) - go func(result VetResult) {*/ - var ( - iss *github.Issue - err error - ) - if shouldReportToGithub(result.FilePath) { - issueRequest := CreateIssueRequest(result) - iss, _, err = ir.bot.client.CreateIssue(ir.owner, ir.repo, &issueRequest) - if err != nil { - log.Printf("error opening new issue: %v", err) - return + ir.bot.wg.Add(1) + go func(result VetResult) { + var ( + iss *github.Issue + err error + ) + if shouldReportToGithub(result.FilePath) { + issueRequest := CreateIssueRequest(result) + iss, _, err = ir.bot.client.CreateIssue(ir.owner, ir.repo, &issueRequest) + if err != nil { + log.Printf("error opening new issue: %v", err) + return + } } - } - ir.persistResult(result, iss, md5Sum) - log.Printf("opened new issue at %s", iss.GetHTMLURL()) - /*ir.bot.wg.Done() - }(result)*/ + ir.persistResult(result, iss, md5Sum) + ir.bot.wg.Done() + }(result) } func shouldReportToGithub(filepath string) bool { - if strings.HasSuffix(filepath, "_test.go") || strings.HasPrefix(filepath, "vendor/") { + if strings.HasSuffix(filepath, "_test.go") || + strings.Contains(filepath, "vendor/") || + strings.Contains(filepath, "test/") { return false } return true @@ -97,7 +96,7 @@ func shouldReportToGithub(filepath string) bool { // persistResult writes the provided VetResult and github.Issue to the database (if the issue is non-nil). // It is not thread-safe (yet). func (ir *IssueReporter) persistResult(result VetResult, issue *github.Issue, md5Sum [16]byte) error { - _, err := db.FindingDAO.Create(context.Background(), ir.bot.db, db.Finding{ + createResult, err := db.FindingDAO.Create(context.Background(), ir.bot.db, db.Finding{ GithubOwner: result.Owner, GithubRepo: result.Repo, Filepath: result.FilePath, @@ -112,7 +111,7 @@ func (ir *IssueReporter) persistResult(result VetResult, issue *github.Issue, md if err != nil { return fmt.Errorf("error persisting finding: %w", err) } - findingID, err := db.LastInsertID(ir.bot.db) // TODO: not this; + findingID, err := createResult.LastInsertId() if err != nil { return fmt.Errorf("error retrieving finding ID: %w", err) } @@ -129,6 +128,7 @@ func (ir *IssueReporter) persistResult(result VetResult, issue *github.Issue, md if err != nil { return fmt.Errorf("error persisting issue: %w", err) } + log.Printf("opened new issue at %s", issue.GetHTMLURL()) return nil } diff --git a/go.mod b/go.mod index d4c0e7e..2551905 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,8 @@ go 1.15 require ( github.com/google/go-github v17.0.0+incompatible github.com/google/go-github/v32 v32.1.0 - github.com/jonbodner/proteus v0.13.0 + github.com/jonbodner/proteus v0.13.0 // indirect + github.com/kalexmills/proteus v0.13.3 github.com/mattn/go-sqlite3 v2.0.3+incompatible github.com/stretchr/testify v1.4.0 golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 diff --git a/go.sum b/go.sum index 89d363e..34f66db 100644 --- a/go.sum +++ b/go.sum @@ -49,6 +49,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -115,6 +116,10 @@ github.com/jonbodner/stackerr v1.0.0 h1:rAe+Fh13cfC9IGuKE4YWiVCzwt9zce9Saldpc8fY github.com/jonbodner/stackerr v1.0.0/go.mod h1:In1ShJr570PDuDHbYfymEQle+H7PgY9KpT+alyk0nEM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kalexmills/proteus v0.13.2 h1:k1yyr7eO45eqgl2C4YF0k2xxaIx+BJgHYytDvmuqisM= +github.com/kalexmills/proteus v0.13.2/go.mod h1:VUHrQAW8w68HtAEkBoxgWTQcNSQ6Wzqxd2oj8esPIp0= +github.com/kalexmills/proteus v0.13.3 h1:jrbNeodifnn9wosnPTEqcfDAFKbUgJL+OVY6xruMM0M= +github.com/kalexmills/proteus v0.13.3/go.mod h1:VUHrQAW8w68HtAEkBoxgWTQcNSQ6Wzqxd2oj8esPIp0= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -122,6 +127,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= @@ -129,14 +135,12 @@ github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdL github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rickar/props v0.0.0-20170718221555-0b06aeb2f037 h1:HFsTO5S+nnw/Xs9lRYF+UUJvH8wMSRMRal321W0hfdY= github.com/rickar/props v0.0.0-20170718221555-0b06aeb2f037/go.mod h1:F1p8BNM4IXv2UcptwSp8HJOapKurodd/PYu1D6Gtn9Y= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -146,12 +150,10 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -182,7 +184,6 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -209,14 +210,12 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 h1:Mj83v+wSRNEar42a/MQgxk9X42TdEmrOl9i+y8WbxLo= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -300,12 +299,10 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -328,7 +325,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -380,16 +376,12 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/db/db_test.go b/internal/db/db_test.go index 0f32d79..86b7d5c 100644 --- a/internal/db/db_test.go +++ b/internal/db/db_test.go @@ -43,13 +43,15 @@ func TestMain(m *testing.M) { func TestIssueDAO(t *testing.T) { ctx := context.Background() - count, err := db.IssueDAO.Upsert(ctx, DB, db.Issue{ + result, err := db.IssueDAO.Upsert(ctx, DB, db.Issue{ GithubOwner: "test", GithubRepo: "123", GithubID: 2, }) - assert.EqualValues(t, 1, count) assert.NoError(t, err) + count, err := result.RowsAffected() + assert.NoError(t, err) + assert.EqualValues(t, 1, count) issue, err := db.IssueDAO.FindByCoordinates(ctx, DB, "test", "123", 2) assert.NoError(t, err) @@ -61,7 +63,11 @@ func TestIssueDAO(t *testing.T) { issue.ExpertAssessment = "confused" issue.SetExpertsDisagree(true) - count, err = db.IssueDAO.Upsert(ctx, DB, issue) + result, err = db.IssueDAO.Upsert(ctx, DB, issue) + assert.NoError(t, err) + count, err = result.RowsAffected() + assert.NoError(t, err) + assert.EqualValues(t, 1, count) issue, err = db.IssueDAO.FindByCoordinates(ctx, DB, "test", "123", 2) assert.NoError(t, err) @@ -72,9 +78,11 @@ func TestIssueDAO(t *testing.T) { func TestRepositoryDAO(t *testing.T) { ctx := context.Background() - count, err := db.RepositoryDAO.Upsert(ctx, DB, db.NewRepository("test", "123")) - assert.EqualValues(t, 1, count) + result, err := db.RepositoryDAO.Upsert(ctx, DB, db.NewRepository("test", "123")) + assert.NoError(t, err) + count, err := result.RowsAffected() assert.NoError(t, err) + assert.EqualValues(t, 1, count) repo, err := db.RepositoryDAO.FindByID(ctx, DB, "test", "123") assert.NoError(t, err) @@ -83,7 +91,9 @@ func TestRepositoryDAO(t *testing.T) { assert.Equal(t, db.RepoStateFresh, repo.State) repo.State = db.RepoStateVisited - count, err = db.RepositoryDAO.Upsert(ctx, DB, repo) + result, err = db.RepositoryDAO.Upsert(ctx, DB, repo) + assert.NoError(t, err) + count, err = result.RowsAffected() assert.NoError(t, err) assert.EqualValues(t, 1, count) @@ -91,9 +101,11 @@ func TestRepositoryDAO(t *testing.T) { assert.NoError(t, err) assert.Equal(t, db.RepoStateVisited, repo.State) - count, err = db.RepositoryDAO.Upsert(ctx, DB, db.NewRepository("test", "456")) - assert.EqualValues(t, 1, count) + result, err = db.RepositoryDAO.Upsert(ctx, DB, db.NewRepository("test", "456")) + assert.NoError(t, err) + count, err = result.RowsAffected() assert.NoError(t, err) + assert.EqualValues(t, 1, count) visitedRepos, err := db.RepositoryDAO.ListByState(ctx, DB, db.RepoStateVisited) assert.NoError(t, err) @@ -110,9 +122,11 @@ func TestRepositoryDAO(t *testing.T) { func TestGopherDAO(t *testing.T) { ctx := context.Background() - count, err := db.GopherDAO.Upsert(ctx, DB, db.Gopher{Username: "kalexmills"}) - assert.EqualValues(t, 1, count) + result, err := db.GopherDAO.Upsert(ctx, DB, db.Gopher{Username: "kalexmills"}) + assert.NoError(t, err) + count, err := result.RowsAffected() assert.NoError(t, err) + assert.Equal(t, int64(1), count) g, err := db.GopherDAO.FindByUsername(ctx, DB, "kalexmills") assert.NoError(t, err) @@ -122,9 +136,11 @@ func TestGopherDAO(t *testing.T) { g.AssessmentCount = 2 g.DisagreementCount = 5 - count, err = db.GopherDAO.Upsert(ctx, DB, g) - assert.EqualValues(t, 1, count) + result, err = db.GopherDAO.Upsert(ctx, DB, g) + assert.NoError(t, err) + count, err = result.RowsAffected() assert.NoError(t, err) + assert.Equal(t, int64(1), count) g, err = db.GopherDAO.FindByUsername(ctx, DB, "kalexmills") assert.NoError(t, err) @@ -137,7 +153,7 @@ func TestFindingDAO(t *testing.T) { hash := md5.Sum([]byte("quote")) - count, err := db.FindingDAO.Create(ctx, DB, db.Finding{ + result, err := db.FindingDAO.Create(ctx, DB, db.Finding{ GithubOwner: "owner", GithubRepo: "repo", Filepath: "filepath", @@ -150,13 +166,14 @@ func TestFindingDAO(t *testing.T) { ExtraInfo: "extra", }) assert.NoError(t, err) + count, err := result.RowsAffected() + assert.NoError(t, err) assert.Equal(t, int64(1), count) - - id, err := db.LastInsertID(DB) + id, err := result.LastInsertId() assert.NoError(t, err) - assert.Equal(t, 1, id) + assert.Equal(t, int64(1), id) - count, err = db.FindingDAO.Create(ctx, DB, db.Finding{ + result, err = db.FindingDAO.Create(ctx, DB, db.Finding{ GithubOwner: "owner", GithubRepo: "repo", Filepath: "filepath", @@ -169,11 +186,12 @@ func TestFindingDAO(t *testing.T) { ExtraInfo: "extra", }) assert.NoError(t, err) + count, err = result.RowsAffected() + assert.NoError(t, err) assert.Equal(t, int64(1), count) - - id, err = db.LastInsertID(DB) + id, err = result.LastInsertId() assert.NoError(t, err) - assert.Equal(t, 2, id) + assert.Equal(t, int64(2), id) f, err := db.FindingDAO.FindByID(ctx, DB, 1) assert.NoError(t, err) diff --git a/internal/db/experts.go b/internal/db/experts.go index 0ea08dd..6b2f724 100644 --- a/internal/db/experts.go +++ b/internal/db/experts.go @@ -2,8 +2,9 @@ package db import ( "context" + "database/sql" - "github.com/jonbodner/proteus" + "github.com/kalexmills/proteus" ) // Expert is a GitHub user marked as an expert @@ -13,7 +14,7 @@ type Expert struct { } type ExpertDAOImpl struct { - Upsert func(ctx context.Context, q proteus.ContextExecutor, e Expert) (int64, error) `proq:"q:upsert" prop:"e"` + Upsert func(ctx context.Context, q proteus.ContextExecutor, e Expert) (sql.Result, error) `proq:"q:upsert" prop:"e"` FindByUsername func(ctx context.Context, q proteus.ContextQuerier, username string) (Expert, error) `proq:"q:findByUsername" prop:"username"` } diff --git a/internal/db/findings.go b/internal/db/findings.go index e189f12..0acbe31 100644 --- a/internal/db/findings.go +++ b/internal/db/findings.go @@ -3,9 +3,8 @@ package db import ( "context" "database/sql" - "errors" - "github.com/jonbodner/proteus" + "github.com/kalexmills/proteus" ) type Finding struct { @@ -25,9 +24,9 @@ type Finding struct { type Md5Sum []byte type FindingDaoImpl struct { - Create func(ctx context.Context, e proteus.ContextExecutor, f Finding) (int64, error) `proq:"q:create" prop:"f"` - FindByID func(ctx context.Context, q proteus.ContextQuerier, id int64) (Finding, error) `proq:"q:findById" prop:"id"` - ListChecksums func(ctx context.Context, q proteus.ContextQuerier) ([]Md5Sum, error) `proq:"q:listChecksums"` + Create func(ctx context.Context, e proteus.ContextExecutor, f Finding) (sql.Result, error) `proq:"q:create" prop:"f"` + FindByID func(ctx context.Context, q proteus.ContextQuerier, id int64) (Finding, error) `proq:"q:findById" prop:"id"` + ListChecksums func(ctx context.Context, q proteus.ContextQuerier) ([]Md5Sum, error) `proq:"q:listChecksums"` } var FindingDAO FindingDaoImpl @@ -46,18 +45,3 @@ func init() { panic(err) } } - -// LastInsertID retrieves the last insert ID. Its use is prone to race-conditions in case multiple -// queries are being executed simultaneously. -func LastInsertID(db *sql.DB) (int, error) { - rows, err := db.Query("SELECT last_insert_rowid()") - if err != nil { - return 0, err - } - for rows.Next() { - var result int - rows.Scan(&result) - return result, nil - } - return 0, errors.New("query resulted in zero rows") -} diff --git a/internal/db/gophers.go b/internal/db/gophers.go index 3c80532..8e1d183 100644 --- a/internal/db/gophers.go +++ b/internal/db/gophers.go @@ -2,8 +2,9 @@ package db import ( "context" + "database/sql" - "github.com/jonbodner/proteus" + "github.com/kalexmills/proteus" ) type Gopher struct { @@ -13,7 +14,7 @@ type Gopher struct { } type GopherDAOImpl struct { - Upsert func(ctx context.Context, q proteus.ContextExecutor, g Gopher) (int64, error) `proq:"q:upsert" prop:"g"` + Upsert func(ctx context.Context, q proteus.ContextExecutor, g Gopher) (sql.Result, error) `proq:"q:upsert" prop:"g"` FindByUsername func(ctx context.Context, q proteus.ContextQuerier, username string) (Gopher, error) `proq:"q:findByUsername" prop:"username"` } diff --git a/internal/db/issues.go b/internal/db/issues.go index 2d23d01..2b955ae 100644 --- a/internal/db/issues.go +++ b/internal/db/issues.go @@ -2,12 +2,13 @@ package db import ( "context" + "database/sql" - "github.com/jonbodner/proteus" + "github.com/kalexmills/proteus" ) type Issue struct { - FindingID int `prof:"finding_id"` + FindingID int64 `prof:"finding_id"` GithubOwner string `prof:"github_owner"` GithubRepo string `prof:"github_repo"` GithubID int `prof:"github_id"` @@ -29,7 +30,7 @@ func (i *Issue) SetExpertsDisagree(value bool) { type IssueDAOImpl struct { FindByCoordinates func(ctx context.Context, q proteus.ContextQuerier, owner, repo string, githubID int) (Issue, error) `proq:"q:findByFindingID" prop:"owner,repo,githubID"` - Upsert func(ctx context.Context, q proteus.ContextExecutor, i Issue) (int64, error) `proq:"q:upsert" prop:"i"` + Upsert func(ctx context.Context, q proteus.ContextExecutor, i Issue) (sql.Result, error) `proq:"q:upsert" prop:"i"` } var IssueDAO IssueDAOImpl diff --git a/internal/db/repositories.go b/internal/db/repositories.go index 2337bf0..7605018 100644 --- a/internal/db/repositories.go +++ b/internal/db/repositories.go @@ -2,8 +2,9 @@ package db import ( "context" + "database/sql" - "github.com/jonbodner/proteus" + "github.com/kalexmills/proteus" ) type Repository struct { @@ -31,7 +32,7 @@ func stringToRepoState(str string) RepoState { type RepositoryDaoImpl struct { FindByID func(ctx context.Context, q proteus.ContextQuerier, owner, repo string) (Repository, error) `proq:"q:findByID" prop:"owner,repo"` ListByState func(ctx context.Context, q proteus.ContextQuerier, state RepoState) ([]Repository, error) `proq:"q:listByState" prop:"state"` - Upsert func(ctx context.Context, e proteus.ContextExecutor, r Repository) (int64, error) `proq:"q:upsert" prop:"r"` + Upsert func(ctx context.Context, e proteus.ContextExecutor, r Repository) (sql.Result, error) `proq:"q:upsert" prop:"r"` CountAll func(ctx context.Context, q proteus.ContextQuerier) (int64, error) `proq:"q:count"` }