Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fxorm): Provided module #36

Merged
merged 1 commit into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
- "fxhealthcheck"
- "fxlog"
- "fxmetrics"
- "fxorm"
- "fxtrace"
steps:
- name: Checkout
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/fxorm-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: "fxorm-ci"

on:
push:
branches:
- "feat**"
- "fix**"
- "hotfix**"
- "chore**"
paths:
- "fxorm/**.go"
- "fxorm/go.mod"
- "fxorm/go.sum"
pull_request:
types:
- opened
- synchronize
- reopened
branches:
- main
paths:
- "fxorm/**.go"
- "fxorm/go.mod"
- "fxorm/go.sum"

jobs:
ci:
uses: ./.github/workflows/common-ci.yml
secrets: inherit
with:
module: "fxorm"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Yokai's `Fx modules` are the plugins for your Yokai application.
| [fxhealthcheck](fxhealthcheck) | Fx module for [healthcheck](healthcheck) |
| [fxlog](fxlog) | Fx module for [log](log) |
| [fxmetrics](fxmetrics) | Fx module for [prometheus](https://github.com/prometheus/client_golang) |
| [fxorm](fxorm) | Fx module for [orm](orm) |
| [fxtrace](fxtrace) | Fx module for [trace](trace) |

They can also be used in any [Fx](https://github.com/uber-go/fx) based Go application.
Expand Down
63 changes: 63 additions & 0 deletions fxorm/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
run:
timeout: 5m
concurrency: 8

linters:
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- containedctx
- contextcheck
- decorder
- dogsled
- durationcheck
- errcheck
- errchkjson
- errname
- errorlint
- forbidigo
- forcetypeassert
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofmt
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- govet
- grouper
- importas
- ineffassign
- interfacebloat
- logrlint
- maintidx
- makezero
- misspell
- nestif
- nilerr
- nilnil
- nlreturn
- nolintlint
- nosprintfhostport
- prealloc
- predeclared
- promlinter
- reassign
- staticcheck
- tenv
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- usestdlibvars
- whitespace
244 changes: 244 additions & 0 deletions fxorm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
# Fx ORM Module

[![ci](https://github.com/ankorstore/yokai/actions/workflows/fxorm-ci.yml/badge.svg)](https://github.com/ankorstore/yokai/actions/workflows/fxorm-ci.yml)
[![go report](https://goreportcard.com/badge/github.com/ankorstore/yokai/fxorm)](https://goreportcard.com/report/github.com/ankorstore/yokai/fxorm)
[![codecov](https://codecov.io/gh/ankorstore/yokai/graph/badge.svg?token=ghUBlFsjhR&flag=fxorm)](https://app.codecov.io/gh/ankorstore/yokai/tree/main/fxorm)
[![Deps](https://img.shields.io/badge/osi-deps-blue)](https://deps.dev/go/github.com%2Fankorstore%2Fyokai%2Ffxorm)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/ankorstore/yokai/fxorm)](https://pkg.go.dev/github.com/ankorstore/yokai/fxorm)

> [Fx](https://uber-go.github.io/fx/) module for [orm](https://github.com/ankorstore/yokai/tree/main/orm).

<!-- TOC -->
* [Installation](#installation)
* [Documentation](#documentation)
* [Dependencies](#dependencies)
* [Loading](#loading)
* [Configuration](#configuration)
* [Auto migrations](#auto-migrations)
* [Performance](#performance)
* [Disable Default Transaction](#disable-default-transaction)
* [Cache Prepared Statement](#cache-prepared-statement)
* [Override](#override)
<!-- TOC -->

## Installation

```shell
go get github.com/ankorstore/yokai/fxorm
```

## Documentation

### Dependencies

This module is intended to be used alongside:

- the [fxconfig](https://github.com/ankorstore/yokai/tree/main/fxconfig) module
- the [fxlog](https://github.com/ankorstore/yokai/tree/main/fxlog) module
- the [fxtrace](https://github.com/ankorstore/yokai/tree/main/fxtrace) module

### Loading

To load the module in your Fx application:

```go
package main

import (
"github.com/ankorstore/yokai/fxconfig"
"github.com/ankorstore/yokai/fxlog"
"github.com/ankorstore/yokai/fxorm"
"github.com/ankorstore/yokai/fxtrace"
"go.uber.org/fx"
"gorm.io/gorm"
)

type Model struct {
Name string
}

func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxlog.FxLogModule,
fxtrace.FxTraceModule,
fxorm.FxOrmModule, // load the module
fx.Invoke(func(db *gorm.DB) { // invoke the orm
db.Create(&Model{Name: "some name"})
}),
).Run()
}
```

### Configuration

This module provides the possibility to configure the ORM `driver`:

- `sqlite` for SQLite databases
- `mysql` for MySQL databases
- `postgres` for PostgreSQL databases
- `sqlserver` for SQL Server databases

You can also provide to the ORM the database`dsn`, some `config`, and configure SQL queries `logging` and `tracing`.

```yaml
# ./configs/config.yaml
app:
name: app
env: dev
version: 0.1.0
debug: false
modules:
orm:
driver: mysql # driver to use
dsn: user:pass@tcp(127.0.0.1:3306)/dbname?parseTime=True" # database DSN to connect to
config:
dry_run: false # disabled by default
skip_default_transaction: false # disabled by default
full_save_associations: false # disabled by default
prepare_stmt: false # disabled by default
disable_automatic_ping: false # disabled by default
disable_foreign_key_constraint_when_migrating: false # disabled by default
ignore_relationships_when_migrating: false # disabled by default
disable_nested_transaction: false # disabled by default
allow_global_update: false # disabled by default
query_fields: false # disabled by default
translate_error: false # disabled by default
log:
enabled: true # to log SQL queries, disabled by default
level: info # with a minimal level
values: true # by adding or not clear SQL queries parameters values in logs, disabled by default
trace:
enabled: true # to trace SQL queries, disabled by default
values: true # by adding or not clear SQL queries parameters values in trace spans, disabled by default
```

See [Gorm Config](https://github.com/go-gorm/gorm/blob/master/gorm.go) for more details about the configuration.

### Auto migrations

This module provides the possibility to run automatically your [schemas migrations](https://gorm.io/docs/migration.html)
with `RunFxOrmAutoMigrate()`:

```go
package main

import (
"github.com/ankorstore/yokai/fxconfig"
"github.com/ankorstore/yokai/fxlog"
"github.com/ankorstore/yokai/fxorm"
"github.com/ankorstore/yokai/fxtrace"
"go.uber.org/fx"
"gorm.io/gorm"
)

type Model struct {
Name string
}

func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxlog.FxLogModule,
fxtrace.FxTraceModule,
fxorm.FxOrmModule, // load the module
fxorm.RunFxOrmAutoMigrate(&Model{}), // run auto migration for Model
fx.Invoke(func(db *gorm.DB) { // invoke the orm
db.Create(&Model{Name: "some name"})
}),
).Run()
}
```

### Performance

See [Gorm performance recommendations](https://gorm.io/docs/performance.html).

#### Disable Default Transaction

Gorm performs write (create/update/delete) operations by default inside a transaction to ensure data consistency, which
is not optimized for performance.

You can disable it in the configuration:

```yaml
# ./configs/config.yaml
app:
name: app
env: dev
version: 0.1.0
debug: false
modules:
orm:
driver: mysql # driver to use
dsn: user:pass@tcp(127.0.0.1:3306)/dbname?parseTime=True" # database DSN to connect to
config:
skip_default_transaction: true # disable default transaction
```

#### Cache Prepared Statement

To create a prepared statement when executing any SQL (and cache them to speed up future calls):

```yaml
# ./configs/config.yaml
app:
name: app
env: dev
version: 0.1.0
debug: false
modules:
orm:
driver: mysql # driver to use
dsn: user:pass@tcp(127.0.0.1:3306)/dbname?parseTime=True" # database DSN to connect to
config:
prepare_stmt: true # enable prepared statements
```

### Override

By default, the `gorm.DB` is created by
the [DefaultOrmFactory](https://github.com/ankorstore/yokai/blob/main/orm/factory.go).

If needed, you can provide your own factory and override the module:

```go
package main

import (
"github.com/ankorstore/yokai/fxconfig"
"github.com/ankorstore/yokai/fxlog"
"github.com/ankorstore/yokai/fxorm"
"github.com/ankorstore/yokai/fxtrace"
"github.com/ankorstore/yokai/orm"
"go.uber.org/fx"
"gorm.io/gorm"
)

type CustomOrmFactory struct{}

func NewCustomOrmFactory() orm.OrmFactory {
return &CustomOrmFactory{}
}

func (f *CustomOrmFactory) Create(options ...orm.OrmOption) (*gorm.DB, error) {
return &gorm.DB{...}, nil
}

type Model struct {
Name string
}

func main() {
fx.New(
fxconfig.FxConfigModule, // load the module dependencies
fxlog.FxLogModule,
fxtrace.FxTraceModule,
fxorm.FxOrmModule, // load the module
fx.Decorate(NewCustomOrmFactory), // override the module with a custom factory
fx.Invoke(func(customDb *gorm.DB) { // invoke the custom ORM
customDb.Create(&Model{Name: "custom"})
}),
).Run()
}
```
Loading
Loading