gormgen

package module
v0.0.0-...-2998f4b Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2019 License: MIT Imports: 17 Imported by: 0

README

gormgen

Build Status

gormgen is a code generation tool to generate a better API to query and update gorm structs without having to deal with interface{}s or with database column names.

Note : gormgen is still is still in early development phase. It may contain bugs and the API is not yet stable. Your suggestions for improving gormgen are welcome through issues/PRs.

Why to use gormgen


// Querying

// The gorm way:
users := []User{}
err := db.Where("age > ?", 20).Order("age ASC").Limit(10).Find(&users).Error

// gormgen way
users, err := (&UserQueryBuilder{}).
  WhereAge(gormgen.GreaterThanPredicate, 20).
  OrderByAge(true).
  Limit(10).
  QueryAll(db)


// Creating Object
user := &User{
  Name: "Bla",
  Age: 20,
}

// The gorm way
err := db.Create(user).Error

// The gormgen way
err := user.Save(db)
  • No more ugly interface{}s when doing in the Where function. Using gormgen, the passed values will be type checked.
  • No more ugly strings for column names for Where and Order functions. By this, you won't need to convert the field name to the column name yourself, gormgen will do it for you. Also, you won't forget to change a column name when you change the field name because your code won't compile until you fix it everywhere.
  • Query results are returned in a more intuitive way instead of passing them as a param. Also the errors are returned the "Go" way instead of explicitly accessing them.
  • It doesn't alter your struct, so it's still compatible with gorm and you can still use the gorm way whenever you want (or for missing features in gormgen).

How it works

If you have the following :

import "github.com/jinzhu/gorm"

var client *gorm.DB
//go:generate gormgen -structs User -client client
type User struct {
	ID   uint   `gorm:"primary_key"`
	Name string
	Age  int
}

Run go generate and gormgen will generate for you :

func (t *User) Save(db *gorm.DB) error {/* … */}
func (t *User) Delete(db *gorm.DB) error {/* … */}
type UserQueryBuilder struct {/* … */}
func (qb *UserQueryBuilder) Count() (int, error) {/* … */}
func (qb *UserQueryBuilder) First() (*User, error) {/* … */} // Sorted by primary key
func (qb *UserQueryBuilder) QueryOne() (*User, error) {/* … */} // Sorted by the order specified
func (qb *UserQueryBuilder) QueryAll() ([]User, error) {/* … */}
func (qb *UserQueryBuilder) Limit(limit int) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) Offset(offset int) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) WhereID(p gormgen.Predicate, value uint) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) OrderByID(asc bool) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) WhereName(p gormgen.Predicate, value string) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) OrderByName(asc bool) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) WhereAge(p gormgen.Predicate, value int) *UserQueryBuilder {/* … */}
func (qb *UserQueryBuilder) OrderByAge(asc bool) *UserQueryBuilder {/* … */}

For the actual generated code, check the examples folder.

How to use it

  • go get -u github.com/siskinc/gormgen/...
  • Add the //go:generate comment mentioned above anywhere in your code.
  • Add go generate to your build steps.
  • The generated code will depend on gorm and gormgen, so make sure to vendor both of them.

Not yet supported features

  • Inferring database column name from gorm convention or gorm struct tag.
  • Ignoring fields with gorm:"-".
  • Support for anonymous structs (IMPORTANT for gorm.Model).
  • Support for type aliases.
  • Support for detecting and querying with primary key.
  • Support for the embedded struct tag.

Contributing

Your contributions and ideas are welcomed through issues and pull requests.

Note for development : Make sure to have gormgen in your path to be able to run the tests. Also, always run the tests with make test to regenerate the test structs.

Note

The parser of this package is heavily inspired from the source code of https://godoc.org/golang.org/x/tools/cmd/stringer. That's where I learned how to parse and type check a go package.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	EqualPredicate              = Predicate("=")
	NotEqualPredicate           = Predicate("<>")
	GreaterThanPredicate        = Predicate(">")
	GreaterThanOrEqualPredicate = Predicate(">=")
	SmallerThanPredicate        = Predicate("<")
	SmallerThanOrEqualPredicate = Predicate("<=")
	LikePredicate               = Predicate("LIKE")
)

Functions

This section is empty.

Types

type Generator

type Generator struct {
	// contains filtered or unexported fields
}

The Generator is the one responsible for generating the code, adding the imports, formating, and writing it to the file.

func NewGenerator

func NewGenerator(outputFile string) *Generator

NewGenerator function creates an instance of the generator given the name of the output file as an argument.

func (*Generator) Flush

func (g *Generator) Flush() error

Flush function writes the output to the output file.

func (*Generator) Format

func (g *Generator) Format() error

Format function formates the output of the generation.

func (*Generator) Generate

func (g *Generator) Generate() error

Generate executes the template and store it in an internal buffer.

func (*Generator) Imports

func (g *Generator) Imports() error

Imports function adds the missing imports in the generated code.

func (*Generator) Init

func (g *Generator) Init(parser *Parser, structs []string, client string) error

Init function should be called before any other function is called. It takes a parser that has already parsed the directory that contains the types we want to generate code for. It also takes the name of the structs that we want to generate code for.

type Parser

type Parser struct {
	PkgName string
	// contains filtered or unexported fields
}

The Parser is used to parse a directory and expose information about the structs defined in the files of this directory.

func NewParser

func NewParser() *Parser

NewParser create a new parser instance.

func (*Parser) GetTypeByName

func (p *Parser) GetTypeByName(name string) *types.Struct

GetTypeByName takes the name of the struct and returns a pointer to types.Struct which contains all the information about this struct. It returns nil if the struct is not found.

func (*Parser) ParseDir

func (p *Parser) ParseDir(dir string)

ParseDir should be called before any type querying for the parser. It takes the directory to be parsed and extracts all the structs defined in this directory.

type Predicate

type Predicate string

Predicate is a string that acts as a condition in the where clause

Directories

Path Synopsis
cmd
internal
tmp

Jump to

Keyboard shortcuts

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