Skip to content

malpou/unusedsqlc

Repository files navigation

unusedsqlc

A linter for finding unused sqlc queries in your Go code.

What it does

This tool scans your SQL files for sqlc query definitions and checks if they're actually being used in your Go code. It helps you identify and remove dead queries that are no longer needed.

The linter automatically detects and uses your sqlc.yaml configuration file to find query locations, so it works out of the box with your existing sqlc setup.

Installation

As a standalone tool

go install github.com/malpou/unusedsqlc/cmd/unusedsqlc@latest

As a library

go get github.com/malpou/unusedsqlc

Usage

CLI Tool

# Analyze current directory
unusedsqlc

# Analyze specific directory
unusedsqlc -dir ./pkg/db

# Output as JSON
unusedsqlc -format json

# Exclude specific queries
unusedsqlc -exclude GetUser,GetPost

# Exclude query patterns
unusedsqlc -exclude-patterns 'Test*,*Internal'

# Verbose output
unusedsqlc -verbose

As a Library

package main

import (
    "go/parser"
    "go/token"
    "log"
    
    "github.com/malpou/unusedsqlc"
)

func main() {
    // Parse Go files
    fset := token.NewFileSet()
    pkgs, err := parser.ParseDir(fset, ".", nil, parser.ParseComments)
    if err != nil {
        log.Fatal(err)
    }
    
    var files []*ast.File
    for _, pkg := range pkgs {
        for _, file := range pkg.Files {
            files = append(files, file)
        }
    }
    
    // Configure and run the linter
    config := unusedsqlc.DefaultConfig()
    config.ExcludePatterns = []string{"Test*"}
    
    linter := unusedsqlc.New(config)
    messages, err := linter.Run(files, fset, ".")
    if err != nil {
        log.Fatal(err)
    }
    
    // Process results
    for _, msg := range messages {
        log.Printf("%s:%d: %s\n", msg.Pos.Filename, msg.Pos.Line, msg.Message)
    }
}

Configuration

The linter automatically reads your sqlc.yaml file to find query locations. You can exclude specific queries using command-line flags:

# Exclude specific queries by name
unusedsqlc -exclude GetSystemUser,GetConfig

# Exclude queries matching patterns
unusedsqlc -exclude-patterns 'Test*,*_test,*Internal'

When using as a library:

config := unusedsqlc.DefaultConfig()
config.ExcludeQueries = []string{"GetSystemUser"}
config.ExcludePatterns = []string{"Test*", "*_test", "*Internal"}

The exclude patterns support wildcards (*) for prefix, suffix, and substring matching.

How it works

The linter does three things:

  1. Reads your sqlc.yaml to find query files (or searches common directories if no config is found)
  2. Parses SQL files to find sqlc query definitions (the -- name: QueryName :type comments)
  3. Analyzes your Go code to see which queries are actually being called
  4. Reports any queries that exist but are never used

It understands all the standard sqlc query types: :one, :many, :exec, :execrows, :execresult, and :copyfrom.

Integration with golangci-lint

To use with golangci-lint, add it as a custom linter in your .golangci.yml:

linters-settings:
  custom:
    unusedsqlc:
      path: github.com/malpou/unusedsqlc
      description: Find unused SQLc queries
      original-url: github.com/malpou/unusedsqlc

Example

Say you have a SQL file with these queries:

-- name: GetUser :one
SELECT * FROM users WHERE id = $1;

-- name: UnusedQuery :many
SELECT * FROM users WHERE active = true;

And your Go code only uses GetUser:

func main() {
    db, _ := sql.Open("postgres", "...")
    queries := New(db)
    
    user, _ := queries.GetUser(ctx, 1)
    // UnusedQuery is never called
}

Running the linter will output:

queries.sql:4: unused sqlc query "UnusedQuery" defined at queries.sql:4

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

MIT

About

A linter for finding unused sqlc queries in your Go code

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors