ent
ent runs on database/sql, so the simplest coverage is to point entsql
at a *sql.DB from sqlguard.Register / OpenDB. entguard is the
dedicated alternative: it decorates ent's own dialect.Driver, the same
seam ent's built-in dialect.Debug wrapper uses, so it works regardless of
how the *sql.DB was opened and gives you a handle for ResetN1().
go get github.com/KARTIKrocks/sqlguard/integrations/entguard
import (
"entgo.io/ent/dialect"
entsql "entgo.io/ent/dialect/sql"
"github.com/KARTIKrocks/sqlguard/integrations/entguard"
"github.com/KARTIKrocks/sqlguard/middleware"
"myapp/ent"
)
drv, err := entsql.Open(dialect.Postgres, dsn)
guarded := entguard.Wrap(drv,
middleware.WithSlowQueryThreshold(500*time.Millisecond),
middleware.WithN1Detection(10, time.Second),
)
client := ent.NewClient(ent.Driver(guarded))
API
| Symbol | Use |
|---|---|
entguard.Wrap(d dialect.Driver, opts ...middleware.Option) *Driver | Decorate any dialect.Driver — including one already wrapped by dialect.Debug. |
(*Driver).ResetN1() | Clear N+1 state at a request boundary. |
Exec, Query, Tx, BeginTx | The dialect.Driver methods; ent calls them. |
guarded := entguard.Wrap(drv, middleware.WithN1Detection(10, time.Second))
func handler(w http.ResponseWriter, r *http.Request) {
defer guarded.ResetN1()
// ...
}
What is covered
ExecandQueryon the driver.TxandBeginTx, and everyExec/Queryon the transactions they return. Statements inside a transaction are analyzed exactly like the ones outside it.
Every call flows through middleware.Guard.Observe: static rules run on
each statement, latency is reported only when it succeeded.
Notes
- ent's generated client issues predictable, parameterized SQL, which is the case the analysis cache was built for — after the first call each query shape is a cache hit.
- Do not combine
entguardwith a driver-levelsqlguard.Registeron the same*sql.DB; each statement would be analyzed twice.