goone

package module
v1.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2022 License: MIT Imports: 17 Imported by: 6

README

test_and_lint

goone

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

Example

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

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!

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name: "goone",
	Doc:  doc,
	Run:  run,

	Requires: []*analysis.Analyzer{
		inspect.Analyzer,
	},
}

Analyzer is analysis files

Functions

This section is empty.

Types

type FuncCache

type FuncCache struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewFuncCache

func NewFuncCache() *FuncCache

func (*FuncCache) Exists

func (m *FuncCache) Exists(key token.Pos) bool

func (*FuncCache) Get

func (m *FuncCache) Get(key token.Pos) bool

func (*FuncCache) Set

func (m *FuncCache) Set(key token.Pos, value bool)

type ReportCache

type ReportCache struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewReportCache

func NewReportCache() *ReportCache

func (*ReportCache) Get

func (m *ReportCache) Get(pass *analysis.Pass, pos token.Pos) bool

func (*ReportCache) Set

func (m *ReportCache) Set(pass *analysis.Pass, pos token.Pos, value bool)

type SearchCache

type SearchCache struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewSearchCache

func NewSearchCache() *SearchCache

func (*SearchCache) Get

func (m *SearchCache) Get(key token.Pos) bool

func (*SearchCache) Set

func (m *SearchCache) Set(key token.Pos, value bool)

type Types

type Types struct {
	Package []struct {
		PkgName   string `yaml:"pkgName"`
		TypeNames []struct {
			TypeName string `yaml:"typeName"`
		} `yaml:"typeNames"`
	} `yaml:"package"`
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL