Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/masibw/goone

goone finds N+1 query in go
https://github.com/masibw/goone

go loop performance sql

Last synced: 29 days ago
JSON representation

goone finds N+1 query in go

Awesome Lists containing this project

README

        

![test_and_lint](https://github.com/masibw/go_one/workflows/test_and_lint/badge.svg)

# goone
goone finds N+1(strictly speaking call SQL in a for loop) query in go

## Example
```go
package main

import (
"database/sql"
"fmt"
"log"

_ "github.com/go-sql-driver/mysql"
)

type Person struct {
Name string
JobID int
}

type Job struct {
JobID int
Name string
}

func main(){

cnn, _ := sql.Open("mysql", "user:password@tcp(host:port)/dbname")

rows, _ := cnn.Query("SELECT name, job_id FROM persons")

defer rows.Close()

for rows.Next() {
var person Person
if err := rows.Scan(&person.Name,&person.JobID); err != nil {
log.Fatal(err)
}

var job Job

// This is N+1 query
if err := cnn.QueryRow("SELECT job_id, name FROM Jobs WHERE job_id = ?",person.JobID).Scan(&job.JobID,&job.Name); err != nil {
log.Fatal(err)
}
fmt.Println(person.Name,job.Name)
}

}
```

## output
```
./hoge.go:38:13: this query is called in a loop
```

# Install
```
go get github.com/masibw/goone/cmd/goone
```

# Usage

## bash
```
go vet -vettool=`which goone` ./...
```

## fish
```
go vet -vettool=(which goone) ./...
```

## CI
### Github Actions
```
- name: install goone
run: go get -u github.com/masibw/goone/cmd/goone
- name: run goone
run: go vet -vettool=`which goone` -goone.configPath="$PWD/goone.yml" ./...
```

# Library Support
- sql
- sqlx
- gorp
- gorm

You can add types to detect sql query.

# Config
You can add any types that you want to detect as sql query.
You can also detect the case where an interface is in between by writing below. example [project](https://github.com/masibw/go_todo)
```yaml:goone.yml
package:
- pkgName: 'github.com/masibw/go_todo/cmd/go_todo/infrastructure/api/handler'
typeNames:
- typeName: '*todoHandler'
```
goone searches for `goone.yml` in directories up to the root from the file directory which analyzing currently. (not the working directory(command executed))

You can use the `-goone.configPath` flag at runtime to indicate config by an absolute path.

## Example

If goone.yml exists in the directory where the command was executed
```
go vet -vettool=`which goone` -goone.configPath="$PWD/goone.yml" ./...
```

# Contribute
You're welcome to build an Issue or create a PR and be proactive!