dbie

package module
v0.0.0-...-1dcaae5 Latest Latest
Warning

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

Go to latest
Published: Feb 23, 2023 License: MIT Imports: 3 Imported by: 4

README

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*

Mongo:

Bun:

Gorm:

go-pg:

Documentation

Index

Constants

View Source
const (
	Eq = iota + 0
	Neq
	Gt
	Gte
	Lt
	Lte
	Like
	Ilike
	Nlike
	Nilike
	In
	Nin
	Is
	Not
)
View Source
const (
	ASC = 0 + iota
	DESC
)

Variables

View Source
var ErrNoRows = Error{sql.ErrNoRows}

Functions

func Wrap

func Wrap(err error) error

Types

type CardinalityViolationError

type CardinalityViolationError string

func (CardinalityViolationError) Error

type Error

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

func (Error) Error

func (e Error) Error() string

type IntegrityConstraintViolationError

type IntegrityConstraintViolationError string

func (IntegrityConstraintViolationError) Error

type InvalidCursorStateError

type InvalidCursorStateError string

func (InvalidCursorStateError) Error

func (e InvalidCursorStateError) Error() string

type InvalidTransactionStateError

type InvalidTransactionStateError string

func (InvalidTransactionStateError) Error

type Op

type Op int

func (Op) String

func (op Op) String() string

type Page

type Page struct {
	Offset int `json:"offset,omitempty"`
	Limit  int `json:"limit,omitempty"`
}

Page Paginated request

type Paginated

type Paginated[Entity any] struct {
	Data   []Entity `json:"data,omitempty"`
	Offset int      `json:"offset,omitempty"`
	Limit  int      `json:"limit,omitempty"`
	Count  int      `json:"count,omitempty"`
	Order  []Sort   `json:"order,omitempty"`
}

Paginated result

type Repo

type Repo[Entity any] interface {
	Init() error
	Insert(item ...Entity) error
	Select(field string, operator Op, val any, orders ...Sort) ([]Entity, error)
	SelectOne(field string, operator Op, val any, orders ...Sort) (Entity, error)
	SelectPage(page Page, field string, operator Op, val any, orders ...Sort) (items Paginated[Entity], err error)
	Close() error
}

type Sort

type Sort struct {
	Field string    `json:"field,omitempty"`
	Order SortOrder `json:"order,omitempty"`
}

type SortOrder

type SortOrder int

func (SortOrder) String

func (s SortOrder) String() string

type TransactionRollbackError

type TransactionRollbackError string

func (TransactionRollbackError) Error

func (e TransactionRollbackError) Error() string

Directories

Path Synopsis
bun Module
gorm Module
mongo Module
pg Module

Jump to

Keyboard shortcuts

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