package db import ( "context" "database/sql" "database/sql/driver" "time" "contrib.go.opencensus.io/integrations/ocsql" "entgo.io/ent/dialect" entsql "entgo.io/ent/dialect/sql" pgx "github.com/jackc/pgx/v5/stdlib" "gitserver.in/patialtech/rano/config" "gitserver.in/patialtech/rano/db/ent" "gitserver.in/patialtech/rano/util/logger" ) type connector struct { dsn string } // New *sql.DB instance func New() *sql.DB { databaseUrl := config.Read().DbURL db := sql.OpenDB(connector{dsn: databaseUrl}) db.SetMaxOpenConns(50) db.SetMaxIdleConns(5) db.SetConnMaxLifetime(0) // Maximum amount of time a connection can be reused (0 means no limit) return db } func (c connector) Connect(context.Context) (driver.Conn, error) { return c.Driver().Open(c.dsn) } func (connector) Driver() driver.Driver { return ocsql.Wrap( pgx.GetDefaultDriver(), ocsql.WithAllTraceOptions(), ocsql.WithRowsClose(false), ocsql.WithRowsNext(false), ocsql.WithDisableErrSkip(true), ) } // Client for pgx // // https://entgo.io/docs/sql-integration func Client() *ent.Client { // Create an ent.Driver from `db`. drv := entsql.OpenDB(dialect.Postgres, New()) cl := ent.NewClient(ent.Driver(drv)) cl.Use(AuditHook) return cl } // A AuditHook is an example for audit-log hook. func AuditHook(next ent.Mutator) ent.Mutator { type Entity interface { GetID() (int64, error) } return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (v ent.Value, err error) { var id int64 start := time.Now() defer func() { saveAudit(ctx, id, m.Type(), m.Op().String(), time.Since(start), err) }() v, err = next.Mutate(ctx, m) if en, ok := v.(Entity); ok { id, _ = en.GetID() } logger.Info("** %v", v) return }) } func saveAudit(_ context.Context, entID int64, entT, op string, d time.Duration, err error) { logger.Info("audit: %d, %s, %s, %s, %v", entID, entT, op, d, err) // ml.SetCreatedAt(time.Now()) // if usr := auth.CtxUser(ctx); usr != nil { // ml.SetByID(usr.ID) // ml.SetBy(usr.DisplayName) // } // switch op := m.Op(); { // case op.Is(ent.OpCreate): // ml.SetOperation("Create") // case op.Is(ent.OpUpdate): // ml.SetOperation("Update") // case op.Is(ent.OpUpdateOne): // ml.SetOperation("UpdateOne") // case op.Is(ent.OpDelete): // ml.SetOperation("Delete") // case op.Is(ent.OpDeleteOne): // ml.SetOperation("DeleteOne") // } }