Skip to content
This repository was archived by the owner on Dec 22, 2024. It is now read-only.

iamgoroot/dbie

Folders and files

NameName
Last commit message
Last commit date
Sep 12, 2022
Feb 23, 2023
Feb 23, 2023
May 29, 2022
Sep 14, 2022
Jul 31, 2022
Jun 18, 2022
Jul 31, 2022
Jul 31, 2022
Jul 3, 2022
Jul 31, 2022
Jul 31, 2022
Jul 31, 2022
Jul 31, 2022

Repository files navigation

dbie

codecov

dbie - (DB Interface Extension) Golang database layer for lazy gophers

Long story short:

  1. Why it might be good?
  2. Why not sqlc?
  3. What's missing
  4. Getting started
    1. Install
    2. Define contracts
    3. Usage
  5. SelectBy*|FindBy*
  6. Sort order
  7. Custom methods

Why it might be good?

  • 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

Why not sqlc?

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)

What's missing?

But... I want to define interfaces at layer where I use them!

...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)

Getting started

Install generator tool

   go get -u github.com/iamgoroot/dbietool
   go install github.com/iamgoroot/dbietool

Define repository interface

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)
}

Define model

As usually in Bun, Gorm, go-pg or Mongo (tag bson):

type User struct {
	ID       int
	Name     string
	Group    string
}

Generate

That's it. generate code

go generate ./...

Usage

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())

SelectBy*|FindBy*

Can be used to select items by some criteria.

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

Sort order

  • {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)

Custom methods

  1. Create separate file in same package as repo implementation
  2. Create method with desired signature that does start with SelectBy* or FindBy*

Docs and Links

Mongo:

Bun:

Gorm:

go-pg: