dbie - (DB Interface Extension) Golang database layer for lazy gophers
- You provide an interface of database layer using models from your orm library (Go-pg, Gorm, Bun , mongo etc...)
- dbie generates an implementation of that interface for matching methods
- You can implement custom method yourself if you need
- Why it might be good?
- Why not sqlc?
- What's missing
- Getting started
- SelectBy*|FindBy*
- Sort order
- Custom methods
- You do mostly brain-dead simple db queries (Go-pg, Gorm , Bun, mongo etc...)
- It's a nice addition to orm you might already use - use pagination, sorting, filtering with
- No query pieces all over your code - go code first
- dbietool generates 'just enough' code to satisfy the interface - for less clutter
- Generate and forget - maintain your models and dbie will translate the rest
bdie is different in a few ways so might not be for you depending on your use case or preferences
- Go code first approach
- MongoDB support
- dbie is not a code generator, it's a library - you don't necessarily have to generate any code (it's just your convenience)
- No Transactions - but you can them implement as custom method with your orm library
- No Joins - but custom method again
...And I encourage you to do so!
- Use interface as blueprint for your dbie implementation in database layer
- Define small interfaces in your service layer exactly where you need them (it's golang after all)
go get -u github.com/iamgoroot/dbietool
go install github.com/iamgoroot/dbietool
Define methods you want implemented by using [naming convention](#Naming convention) and use
wrappers for pagination (dbie.Page
and dbie.Paginated
)
//go:generate dbietool -core=Bun,Gorm,Pg -constr=factory
type User interface {
dbie.Repo[model.User]
Init() error
SelectByName(string) ([]model.User, error)
SelectByID(int) (model.User, error)
FindByID(int) (model.User, error)
SelectByGroupEq(string) ([]model.User, error)
SelectByGroup(dbie.Page, string) (items dbie.Paginated[model.User], err error)
SelectByGroupIn(dbie.Page, ...string) (items dbie.Paginated[model.User], err error)
SelectByGroupNinOrderByGroupAsc(dbie.Page, ...string) (items dbie.Paginated[model.User], err error)
SelectByGroupOrderByNameDescOrderByIDAsc(string) (model.User, error)
}
As usually in Bun, Gorm, go-pg or Mongo (tag bson
):
type User struct {
ID int
Name string
Group string
}
That's it. generate code
go generate ./...
func main() {
// instantiate (run dbietool with `-constr=func` parameter)
userRepo := repo.NewUser(context.Background())
// insert user and handle error
err := userRepo.Insert(model.User{Name: "userName1"})
if err != nil {
log.Fatalln(err)
}
// select user using generated method and handle error
user, err := userRepo.SelectByName("userName1")
if err != nil {
log.Fatalln(err)
}
log.Println(user, err)
}
Run dbietool with flag -constr=factory
to generate factory objects instead of factory functions
factory := repo.Bun[model.User]{DB: db}
userRepo := factory.NewUser(context.Background())
Can be used to select items by some criteria.
For now only one criteria is supported per method.
- {ColumnName} - part of function name, specifically db column name but CamelCase instead of snake_case
- {?Operator} - SQL operator.
dbie.Eq
if omitted.- Possible values:
"Eq" (default), "Neq", "Gt", "Gte", "Lt", "Lte", "Like", "Ilike", "Nlike", "Nilike", "In", "Nin", "Is", "Not"
- {columnName} - columnName in camelCase.
- {columnType} - type of parameter as golang type
- Supported return types:
- MODEL - returns one item
- []MODEL - returns slice of resulting items
- dbie.Paginated[MODEL] - returns paginated wrapper with resulting items
- Each method returns error as second parameter
func SelectBy{ColumnName}({columnName} {columnType}) (MODEL, error) // returns one row or error
func FindBy{ColumnName}({columnName} {columnType}) (MODEL, error) // same as above
func SelectBy{ColumnName}{?Operator}( {columnName} {columnType} ) (MODEL, error) // returns one row or error
func SelectBy{ColumnName}{?Operator}( {columnName} {columnType} ) ([]MODEL, error) // returns slice or error
func SelectBy{ColumnName}{?Operator}( {columnName} {columnType} ) (dbie.Paginated[MODEL], error) // returns slice wrapper with pagination or error
- {OrderColumnName} - ColumnName to order by in CamelCase.
- {?SortOrder} - Asc or Desc
- columnName and columnType as in previous example
- composite sorting is supported
func SelectByColumnNameOrderBy{OrderColumnName}{?SortOrder}(columnName columnType) ([]MODEL, error)
func SelectByColumnNameOrderBy{OrderColumnName}{?SortOrder}{ColumnName2}{?Order2}(columnName columnType) ([]MODEL, error)
- Create separate file in same package as repo implementation
- Create method with desired signature that does start with SelectBy* or FindBy*
Mongo:
Bun:
Gorm:
go-pg: