Skip to content

WillAbides/sqlcgetters

Repository files navigation

sqlcgetters

godoc

sqlcgetters command line tool and go module that generates getters for stucts that were generated by sqlc.

Usage: sqlcgetters <path>

sqlcgetters generates getters for structs generated by sqlc.

Arguments:
  <path>    Path to sqlc output directory.

Flags:
  -h, --help       Show context-sensitive help.
      --version    Output the version and exit.

Outputs to stdout. Example usage:

sqlcgetters ./sqlqueries >  ./sqlqueries/getters.go

If sqlc generates:

type User struct {
    ID        uuid.UUID 
	CreatedAt time.Time
    Name      string 
}

then sqlcgetters will generate:

func (x User) GetID() uuid.UUID {
    return x.ID
}

func (x User) GetCreatedAt() time.Time {
    return x.CreatedAt
}

func (x User) GetName() string {
    return x.Name
}

Why do I need this?

sqlc generates structs with exported fields, so why would you want getters? It's all about interfaces. Take these queries for example:

-- name: BooksByTitleYear :many
SELECT book_id, title, authors.name AS author_name, isbn
FROM books
  LEFT JOIN authors ON books.author_id = authors.author_id
WHERE title = $1 AND year = $2;

-- name: BooksByTags :many
SELECT book_id, title, authors.name AS author_name, isbn, tags
FROM books
  LEFT JOIN authors ON books.author_id = authors.author_id
WHERE tags && $1::varchar[];

sqlc will generate two queries with these structs as their results:

type BooksByTitleYearRow struct {
    BookID       int32
    Title        string
    AuthorName   sql.NullString
    Isbn         string
}

type BooksByTagsRow struct {
    BookID       int32
    Title        string
    AuthorName   sql.NullString
    Isbn         string
    Tags         []string
}

You have two different structs with the same fields. Writing a function that handles either of them is difficult. You need to accept interface{} and the type switch to handle the different structs. But if you had a Get*() function for each field, your function can accept an interface with the fields you need.

Name conflicts

If you have columns named both foo and get_foo, then sqlc will create fields named Foo and GetFoo. Normally sqlcgetters will generate a getter for Foo named GetFoo(), but that won't work because the name GetFoo is already in use. In this case, sqlcgetters will append a _ to the end of the method name and create GetFoo_() instead. This shouldn't happen in any sane schema, but it's possible.

Install

go get

go get -u github.com/willabides/sqlcgetters/cmd/sqlcgetters

bindown

Add a bindown dependency:

$ bindown template-source add sqlcgetters https://raw.githubusercontent.com/WillAbides/sqlcgetters/main/bindown.yml
$ bindown dependency add sqlcgetters sqlcgetters#sqlcgetters
Please enter a value for required variable "version":	<latest version>