feat: add database.
This commit is contained in:
37
database/ent/client.go
Normal file
37
database/ent/client.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
|
||||
_ "github.com/jackc/pgx/v4/stdlib"
|
||||
_ "github.com/lib/pq"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
|
||||
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
|
||||
)
|
||||
|
||||
// NewEntClient 创建Ent ORM数据库客户端
|
||||
func NewEntClient[T ClientInterface](cfg *conf.Bootstrap, l *log.Helper, db T) *ClientWrapper[T] {
|
||||
|
||||
drv, err := CreateDriver(
|
||||
cfg.Data.Database.GetDriver(),
|
||||
cfg.Data.Database.GetSource(),
|
||||
cfg.Data.Database.GetEnableTrace(),
|
||||
cfg.Data.Database.GetEnableMetrics(),
|
||||
)
|
||||
if err != nil {
|
||||
l.Fatalf("failed opening connection to db: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
wrapperClient := NewEntClientWrapper(db, drv)
|
||||
|
||||
wrapperClient.SetConnectionOption(
|
||||
int(cfg.Data.Database.GetMaxIdleConnections()),
|
||||
int(cfg.Data.Database.GetMaxOpenConnections()),
|
||||
cfg.Data.Database.GetConnectionMaxLifetime().AsDuration(),
|
||||
)
|
||||
|
||||
return wrapperClient
|
||||
}
|
||||
119
database/ent/client_wrapper.go
Normal file
119
database/ent/client_wrapper.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
|
||||
|
||||
"github.com/XSAM/otelsql"
|
||||
|
||||
entSql "entgo.io/ent/dialect/sql"
|
||||
)
|
||||
|
||||
type ClientInterface interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
type ClientWrapper[T ClientInterface] struct {
|
||||
db T
|
||||
drv *entSql.Driver
|
||||
}
|
||||
|
||||
func NewEntClientWrapper[T ClientInterface](db T, drv *entSql.Driver) *ClientWrapper[T] {
|
||||
return &ClientWrapper[T]{
|
||||
db: db,
|
||||
drv: drv,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClientWrapper[T]) Client() T {
|
||||
return c.db
|
||||
}
|
||||
|
||||
func (c *ClientWrapper[T]) Driver() *entSql.Driver {
|
||||
return c.drv
|
||||
}
|
||||
|
||||
func (c *ClientWrapper[T]) DB() *sql.DB {
|
||||
return c.drv.DB()
|
||||
}
|
||||
|
||||
// Close 关闭数据库连接
|
||||
func (c *ClientWrapper[T]) Close() error {
|
||||
return c.db.Close()
|
||||
}
|
||||
|
||||
// Query 查询数据
|
||||
func (c *ClientWrapper[T]) Query(ctx context.Context, query string, args, v any) error {
|
||||
return c.Driver().Query(ctx, query, args, v)
|
||||
}
|
||||
|
||||
func (c *ClientWrapper[T]) Exec(ctx context.Context, query string, args, v any) error {
|
||||
return c.Driver().Exec(ctx, query, args, v)
|
||||
}
|
||||
|
||||
// SetConnectionOption 设置连接配置
|
||||
func (c *ClientWrapper[T]) SetConnectionOption(maxIdleConnections, maxOpenConnections int, connMaxLifetime time.Duration) {
|
||||
// 连接池中最多保留的空闲连接数量
|
||||
c.DB().SetMaxIdleConns(maxIdleConnections)
|
||||
// 连接池在同一时间打开连接的最大数量
|
||||
c.DB().SetMaxOpenConns(maxOpenConnections)
|
||||
// 连接可重用的最大时间长度
|
||||
c.DB().SetConnMaxLifetime(connMaxLifetime)
|
||||
}
|
||||
|
||||
func driverNameToSemConvKeyValue(driverName string) attribute.KeyValue {
|
||||
switch driverName {
|
||||
case "mariadb":
|
||||
return semconv.DBSystemMariaDB
|
||||
case "mysql":
|
||||
return semconv.DBSystemMySQL
|
||||
case "postgresql":
|
||||
return semconv.DBSystemPostgreSQL
|
||||
case "sqlite":
|
||||
return semconv.DBSystemSqlite
|
||||
default:
|
||||
return semconv.DBSystemKey.String(driverName)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateDriver 创建数据库驱动
|
||||
func CreateDriver(driverName, dsn string, enableTrace, enableMetrics bool) (*entSql.Driver, error) {
|
||||
var db *sql.DB
|
||||
var drv *entSql.Driver
|
||||
var err error
|
||||
|
||||
if enableTrace {
|
||||
// Connect to database
|
||||
if db, err = otelsql.Open(driverName, dsn, otelsql.WithAttributes(
|
||||
driverNameToSemConvKeyValue(driverName),
|
||||
)); err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("failed opening connection to db: %v", err))
|
||||
}
|
||||
|
||||
drv = entSql.OpenDB(driverName, db)
|
||||
} else {
|
||||
if drv, err = entSql.Open(driverName, dsn); err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("failed opening connection to db: %v", err))
|
||||
}
|
||||
|
||||
db = drv.DB()
|
||||
}
|
||||
|
||||
// Register DB stats to meter
|
||||
if enableMetrics {
|
||||
err = otelsql.RegisterDBStatsMetrics(db, otelsql.WithAttributes(
|
||||
driverNameToSemConvKeyValue(driverName),
|
||||
))
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("failed register otel meter: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
return drv, nil
|
||||
}
|
||||
Reference in New Issue
Block a user