Merge pull request #3 from dikstub-rssa/feat/logger-example
Feat/logger example
This commit is contained in:
+1
-1
@@ -30,4 +30,4 @@ config.yml
|
|||||||
|
|
||||||
# Editor/IDE
|
# Editor/IDE
|
||||||
# .idea/
|
# .idea/
|
||||||
# .vscode/
|
.vscode/*
|
||||||
|
|||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Package main API",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${workspaceFolder}/cmd/main-api"
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// "name": "Launch Package excel migrator",
|
||||||
|
// "type": "go",
|
||||||
|
// "request": "launch",
|
||||||
|
// "mode": "auto",
|
||||||
|
// "program": "${workspaceFolder}/cmd/excelmigrator"
|
||||||
|
// }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -5,8 +5,9 @@ go 1.23.0
|
|||||||
toolchain go1.23.11
|
toolchain go1.23.11
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/karincake/apem v0.0.16-e
|
github.com/karincake/apem v0.0.16-g
|
||||||
github.com/karincake/dodol v0.0.1
|
github.com/karincake/dodol v0.0.1
|
||||||
|
github.com/karincake/lepet v0.0.1
|
||||||
gorm.io/gorm v1.25.10
|
gorm.io/gorm v1.25.10
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@ require (
|
|||||||
github.com/nxadm/tail v1.4.11 // indirect
|
github.com/nxadm/tail v1.4.11 // indirect
|
||||||
github.com/rs/zerolog v1.33.0 // indirect
|
github.com/rs/zerolog v1.33.0 // indirect
|
||||||
golang.org/x/crypto v0.40.0 // indirect
|
golang.org/x/crypto v0.40.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||||
golang.org/x/net v0.42.0 // indirect
|
golang.org/x/net v0.42.0 // indirect
|
||||||
golang.org/x/sys v0.34.0 // indirect
|
golang.org/x/sys v0.34.0 // indirect
|
||||||
golang.org/x/text v0.27.0 // indirect
|
golang.org/x/text v0.27.0 // indirect
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
|||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/karincake/apem v0.0.16-e h1:KGeQYmgNw8luidSWkZyGcMbW1PP3KMRCHMTEHQ7twU8=
|
github.com/karincake/apem v0.0.16-g h1:jPIr/YiaJhVSftdA1PyB2tlDiQtFeTVZohO1qf0qpw0=
|
||||||
github.com/karincake/apem v0.0.16-e/go.mod h1:cQP2sJfDrLRIiwWoaLWw/z8uAya+DWu/FpmYeinMQXM=
|
github.com/karincake/apem v0.0.16-g/go.mod h1:cQP2sJfDrLRIiwWoaLWw/z8uAya+DWu/FpmYeinMQXM=
|
||||||
github.com/karincake/dodol v0.0.1 h1:jUXmJh1r0Ei4fmHPZ6IUkoplW/V9d27L63JEl6zudL0=
|
github.com/karincake/dodol v0.0.1 h1:jUXmJh1r0Ei4fmHPZ6IUkoplW/V9d27L63JEl6zudL0=
|
||||||
github.com/karincake/dodol v0.0.1/go.mod h1:2f1NcvkvY0J3GMUkwILNDYVvRUpz0W3lpPp/Ha/Ld24=
|
github.com/karincake/dodol v0.0.1/go.mod h1:2f1NcvkvY0J3GMUkwILNDYVvRUpz0W3lpPp/Ha/Ld24=
|
||||||
|
github.com/karincake/lepet v0.0.1 h1:eq/cwn5BBg0jWZ1c/MmvhFIBma0zBpVs2LwkfDOncy4=
|
||||||
|
github.com/karincake/lepet v0.0.1/go.mod h1:U84w7olXO3BPJw2Hu6MBonFmJmPKaFjtyAj1HTu3z1A=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
@@ -54,6 +56,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
|
|||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||||
|
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||||
|
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|||||||
@@ -9,9 +9,14 @@ type Createdto struct {
|
|||||||
type ReadListDto struct {
|
type ReadListDto struct {
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
Page int `json:"page"`
|
||||||
|
PageSize int `json:"page_size"`
|
||||||
|
NoPagination int `json:"no_pagination"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReadDetailDto struct {
|
type ReadDetailDto struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
@@ -24,3 +29,9 @@ type Updatedto struct {
|
|||||||
type Deletedto struct {
|
type Deletedto struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MetaDto struct {
|
||||||
|
PageNumber int `json:"page_number"`
|
||||||
|
PageSize int `json:"page_size"`
|
||||||
|
Count int64 `json:"count"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,33 +5,93 @@ Any functions that are available to be used externally.
|
|||||||
package crud
|
package crud
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
dg "github.com/karincake/apem/db-gorm-pg"
|
dg "github.com/karincake/apem/db-gorm-pg"
|
||||||
d "github.com/karincake/dodol"
|
d "github.com/karincake/dodol"
|
||||||
|
|
||||||
|
pl "simrs-vx/pkg/logger"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
e "simrs-vx/internal/domain/main-entities/single"
|
e "simrs-vx/internal/domain/_template/single"
|
||||||
)
|
)
|
||||||
|
|
||||||
const source = "crud"
|
const source = "crud"
|
||||||
|
|
||||||
func Create(input e.Createdto) (*d.Data, error) {
|
func Create(input e.Createdto) (*d.Data, error) {
|
||||||
|
data := e.Single{}
|
||||||
|
|
||||||
|
setData(&data, &input)
|
||||||
|
|
||||||
|
event := pl.Event{
|
||||||
|
Feature: "Create",
|
||||||
|
Source: source,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start log
|
||||||
|
event.Action = "Create"
|
||||||
|
event.Status = "started"
|
||||||
|
pl.SetLogInfo(event, input)
|
||||||
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||||
for i := range createPreMw {
|
for i := range createPreMw {
|
||||||
if err := createPreMw[i](&input, &data, dg.I); err != nil {
|
mwName := fmt.Sprintf("createPreMw[%d]", i)
|
||||||
return nil
|
|
||||||
|
event.Action = mwName
|
||||||
|
event.Status = "started"
|
||||||
|
pl.SetLogInfo(event, data)
|
||||||
|
|
||||||
|
if err := createPreMw[i](&input, &data, tx); err != nil {
|
||||||
|
event.Status = "failed"
|
||||||
|
event.ErrInfo = pl.ErrorInfo{
|
||||||
|
Code: "MW_PRE_FAILED", // TODO: add to lang json
|
||||||
|
Detail: fmt.Sprintf("Pre-middleware %s failed", mwName),
|
||||||
|
Raw: mwErr,
|
||||||
|
}
|
||||||
|
return pl.SetLogError(event, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.Status = "completed"
|
||||||
|
pl.SetLogInfo(event, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dg.I.Create(&data).Error; err != nil {
|
event.Action = "DBCreate"
|
||||||
return nil
|
event.Status = "started"
|
||||||
|
pl.SetLogInfo(event, data)
|
||||||
|
if result, err := CreateData(&data, tx).Error; err != nil {
|
||||||
|
event.Status = "failed"
|
||||||
|
event.ErrInfo = pl.ErrorInfo{
|
||||||
|
Code: "data-create-fail",
|
||||||
|
Detail: "Database insert failed",
|
||||||
|
Raw: err,
|
||||||
|
}
|
||||||
|
return pl.SetLogError(event, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.Status = "completed"
|
||||||
|
pl.SetLogInfo(event, nil)
|
||||||
|
|
||||||
for i := range createPostMw {
|
for i := range createPostMw {
|
||||||
if err := createPostMw[i](&input, &data, dg.I); err != nil {
|
mwName := fmt.Sprintf("createPostMw[%d]", i)
|
||||||
return nil
|
|
||||||
|
event.Action = mwName
|
||||||
|
event.Status = "started"
|
||||||
|
pl.SetLogInfo(event, input)
|
||||||
|
if err := createPostMw[i](&input, &data, tx); err != nil {
|
||||||
|
event.Status = "failed"
|
||||||
|
event.ErrInfo = pl.ErrorInfo{
|
||||||
|
Code: "MW_POST_FAILED", // TODO: add to lang json
|
||||||
|
Detail: fmt.Sprintf("Post-middleware %s failed", mwName),
|
||||||
|
Raw: mwErr,
|
||||||
|
}
|
||||||
|
return pl.SetLogError(event, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.Status = "completed"
|
||||||
|
pl.SetLogInfo(event, nil)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -46,26 +106,129 @@ func Create(input e.Createdto) (*d.Data, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ReadList(input e.ReadListDto) (*d.Data, error) {
|
func ReadList(input e.ReadListDto) (*d.Data, error) {
|
||||||
data := d.Data{}
|
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||||
query := dg.I
|
for i := range readListPreMw {
|
||||||
query.Find(&data)
|
if err := readListPreMw[i](&input, &data, tx); err != nil {
|
||||||
if err := query.Error; err != nil {
|
return nil
|
||||||
return nil, err
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data, meta, err := ReadListData(input, tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range readListPostMw {
|
||||||
|
if err := readListPostMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
return &d.Data{
|
return &d.Data{
|
||||||
Meta: d.II{},
|
Meta: d.IS{
|
||||||
|
"source": source,
|
||||||
|
"structure": "list-data",
|
||||||
|
"status": "fetched",
|
||||||
|
"page_number": strconv.Itoa(meta.PageNumber),
|
||||||
|
"page_size": strconv.Itoa(meta.PageSize),
|
||||||
|
"record_totalCount": strconv.Itoa(meta.Count),
|
||||||
|
},
|
||||||
Data: data,
|
Data: data,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadDetail() {
|
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
|
||||||
|
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||||
|
for i := range readDetailPreMw {
|
||||||
|
if err := readDetailPreMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data, err := ReadDetailData(input, tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for i := range readDetailPostMw {
|
||||||
|
if err := readDetailPostMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return &d.Data{
|
||||||
|
Meta: d.IS{
|
||||||
|
"source": source,
|
||||||
|
"structure": "single-data",
|
||||||
|
"status": "fetched",
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Update(input e.Updatedto) (*d.Data, error) {
|
||||||
|
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||||
|
data, err := ReadDetailData(input, tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
setData(&data, &input)
|
||||||
|
for i := range updatePreMw {
|
||||||
|
if err := updatePreMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := UpdateData(*data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for i := range updatePostMw {
|
||||||
|
if err := updatePostMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return &d.Data{
|
||||||
|
Meta: d.IS{
|
||||||
|
"source": source,
|
||||||
|
"structure": "single-data",
|
||||||
|
"status": "updated",
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Update() {
|
func Delete(input e.Deletedto) (*d.Data, error) {
|
||||||
|
err := dg.I.Transaction(func(tx *gorm.DB) error {
|
||||||
}
|
data, err := ReadDetailData(input, tx)
|
||||||
|
if err != nil {
|
||||||
func Delete() {
|
return nil
|
||||||
|
}
|
||||||
|
for i := range deletePreMw {
|
||||||
|
if err := deletePreMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := DeleteData(data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for i := range deletePostMw {
|
||||||
|
if err := deletePostMw[i](&input, &data, tx); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return &d.Data{
|
||||||
|
Meta: d.IS{
|
||||||
|
"source": source,
|
||||||
|
"structure": "single-data",
|
||||||
|
"status": "deleted",
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,101 @@
|
|||||||
package crud
|
package crud
|
||||||
|
|
||||||
import (
|
import (
|
||||||
e "simrs-vx/internal/domain/main-entities/single"
|
e "simrs-vx/internal/domain/_template/single"
|
||||||
|
|
||||||
dg "github.com/karincake/apem/db-gorm-pg"
|
dg "github.com/karincake/apem/db-gorm-pg"
|
||||||
|
gh "github.com/karincake/getuk"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateData(input e.Createdto, tx ...*gorm.DB) (*e.Single, error) {
|
func CreateData(input *e.Single, dbx ...*gorm.DB) (*e.Single, error) {
|
||||||
data := e.Single{}
|
var tx *gorm.DB
|
||||||
|
if len(dbx) > 0 {
|
||||||
var db *gorm.DB
|
tx = dbx[0]
|
||||||
if tx != nil {
|
|
||||||
db = tx
|
|
||||||
} else {
|
} else {
|
||||||
db = dg.I
|
tx = dg.I
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dg.I.Create(&data).Error; err != nil {
|
if err := tx.Create(&data).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &data, err
|
return &data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReadListData(input e.ReadListDto, dbx ...*gorm.DB) ([]e.Single, *e.MetaDto, error) {
|
||||||
|
data := []e.Single{}
|
||||||
|
pagination := gh.Pagination{}
|
||||||
|
count := int64(0)
|
||||||
|
meta := e.MetaDto{}
|
||||||
|
|
||||||
|
var tx *gorm.DB
|
||||||
|
if len(dbx) > 0 {
|
||||||
|
tx = dbx[0]
|
||||||
|
} else {
|
||||||
|
tx = dg.I
|
||||||
|
}
|
||||||
|
|
||||||
|
tx = tx.
|
||||||
|
Model(&e.Single{}).
|
||||||
|
// Joins("Patient"). // if needed
|
||||||
|
// Preload("Patient"). // if needed
|
||||||
|
Scopes(gh.Filter(input)).
|
||||||
|
Count(&count).
|
||||||
|
Scopes(gh.Paginate(input, &pagination)).
|
||||||
|
Order("CreatedAt DESC")
|
||||||
|
|
||||||
|
if err := tx.Find(&data).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, &meta, nil
|
||||||
|
}
|
||||||
|
return nil, nil, err
|
||||||
|
|
||||||
|
}
|
||||||
|
meta.Count = count
|
||||||
|
meta.PageNumber = pagination.PageNumber
|
||||||
|
meta.PageSize = pagination.PageSize
|
||||||
|
return data, &meta, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDetailData(input e.ReadDetailDto, dbx ...*gorm.DB) (*e.Single, error) {
|
||||||
|
data := e.Single{}
|
||||||
|
|
||||||
|
var tx *gorm.DB
|
||||||
|
if len(dbx) > 0 {
|
||||||
|
tx = dbx[0]
|
||||||
|
} else {
|
||||||
|
tx = dg.I
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.First(&data, input.Id).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateData(input e.Single, dbx ...*gorm.DB) error {
|
||||||
|
var tx *gorm.DB
|
||||||
|
if len(dbx) > 0 {
|
||||||
|
tx = dbx[0]
|
||||||
|
} else {
|
||||||
|
tx = dg.I
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Save(&input).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteData(input *e.Single, dbx ...*gorm.DB) error {
|
||||||
|
var tx *gorm.DB
|
||||||
|
if len(dbx) > 0 {
|
||||||
|
tx = dbx[0]
|
||||||
|
} else {
|
||||||
|
tx = dg.I
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Delete(input).Error
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// Package langhelper provides helper functions for language
|
||||||
|
package langhelper
|
||||||
|
|
||||||
|
import (
|
||||||
|
a "github.com/karincake/apem"
|
||||||
|
l "github.com/karincake/lepet"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cfg struct {
|
||||||
|
LangCfg *l.LangCfg `yaml:"langCfg"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Populate() {
|
||||||
|
cfg := &Cfg{
|
||||||
|
LangCfg: &l.LangCfg{},
|
||||||
|
}
|
||||||
|
a.ParseCfg(&cfg)
|
||||||
|
l.Init(cfg.LangCfg)
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// Package logger provides helper functions for logging
|
||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
lz "github.com/karincake/apem/logger-zerolog"
|
||||||
|
d "github.com/karincake/dodol"
|
||||||
|
l "github.com/karincake/lepet"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Event struct {
|
||||||
|
// Context about the operation
|
||||||
|
Feature string // Feature area, e.g. "Create"
|
||||||
|
Action string // Action being performed, e.g. "DBCreate"
|
||||||
|
Source string // Source of event, usually present in each use case
|
||||||
|
Status string // e.g. "started", "failed", "success"
|
||||||
|
|
||||||
|
// Error context
|
||||||
|
ErrInfo ErrorInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorInfo struct {
|
||||||
|
Code string // used in lang json
|
||||||
|
Detail string
|
||||||
|
Raw error
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLogInfo(e Event, data any) {
|
||||||
|
dataString, _ := json.Marshal(data)
|
||||||
|
lz.O.Info().
|
||||||
|
String("source", e.Source).
|
||||||
|
String("feature", e.Feature).
|
||||||
|
String("action", e.Action).
|
||||||
|
String("status", "started").
|
||||||
|
String("input", string(dataString)).
|
||||||
|
Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLogError(e Event, data any) error {
|
||||||
|
dataString, _ := json.Marshal(data)
|
||||||
|
msg := l.I.Msg(e.ErrInfo.Code)
|
||||||
|
|
||||||
|
lz.O.Error().
|
||||||
|
String("message", msg).
|
||||||
|
String("source", e.Source).
|
||||||
|
String("feature", e.Feature).
|
||||||
|
String("action", e.Action).
|
||||||
|
String("status", e.Status).
|
||||||
|
String("error_code", e.ErrInfo.Code).
|
||||||
|
String("error_detail", e.ErrInfo.Detail).
|
||||||
|
String("data", string(dataString)).
|
||||||
|
Send()
|
||||||
|
|
||||||
|
if err, ok := e.ErrInfo.Raw.(d.FieldError); ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err, ok := e.ErrInfo.Raw.(d.FieldErrors); ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.ErrInfo.Detail != "" {
|
||||||
|
return d.FieldError{Code: e.ErrInfo.Code, Message: e.ErrInfo.Detail}
|
||||||
|
}
|
||||||
|
return d.FieldError{Code: e.ErrInfo.Code, Message: msg}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user