Skip to content

P2: GORM hooks + database/sql middleware for pre-query SQL validation #452

@ajitpratap0

Description

@ajitpratap0

Problem

GORM (39k stars) is the dominant Go ORM. There is no standard pattern for integrating GoSQLX validation before a GORM query executes. This is the most requested integration pattern for enterprise teams who want to gate production queries.

Proposed Integration

GORM Hooks

import (
    "gorm.io/gorm"
    gosqlxgorm "github.com/ajitpratap0/GoSQLX/pkg/integration/gorm"
)

// Register GoSQLX validation as a GORM plugin
db, _ := gorm.Open(postgres.Open(dsn))
db.Use(gosqlxgorm.NewValidator(gosqlxgorm.ValidatorOptions{
    Dialect:     gosqlx.DialectPostgresql,
    LintRules:   []string{"L011", "L012", "L015", "L016"},  // Dangerous ops + perf
    SecurityScan: true,
    BlockOnError: true,  // return error if validation fails
}))

// Now all GORM queries are validated before execution
db.Where("id = ?", userID).Find(&users)
// If SQL fails lint: returns error instead of executing

database/sql Middleware

import gosqlxsql "github.com/ajitpratap0/GoSQLX/pkg/integration/sql"

// Wrap any sql.DB with GoSQLX validation middleware
rawDB, _ := sql.Open("postgres", dsn)
validatedDB := gosqlxsql.NewValidatingDB(rawDB, gosqlxsql.Options{
    Dialect:      gosqlx.DialectPostgresql,
    BlockOnError: false,  // log only; don't block
    Logger:       slog.Default(),
})

// All queries through validatedDB are parsed and analyzed
validatedDB.QueryContext(ctx, "SELECT * FROM users")  // logs warning: SELECT *

Package Structure

pkg/integration/
├── gorm/
│   ├── plugin.go          — GORM plugin implementing gorm.Plugin interface
│   ├── callbacks.go       — GORM BeforeQuery/BeforeCreate/BeforeUpdate/BeforeDelete
│   └── plugin_test.go     — Tests with in-memory SQLite GORM DB
├── sql/
│   ├── db.go              — ValidatingDB wrapper around *sql.DB
│   ├── conn.go            — ValidatingConn for per-connection validation
│   └── db_test.go         — Tests with testcontainers PostgreSQL
└── examples/
    ├── gorm-integration/  — Full working GORM example
    └── sqlx-integration/  — sqlx library integration example

GORM Hooks to Register

// All DML operations
db.Callback().Query().Before("gorm:query").Register("gosqlx:validate", validate)
db.Callback().Create().Before("gorm:create").Register("gosqlx:validate", validate)
db.Callback().Update().Before("gorm:update").Register("gosqlx:validate", validate)
db.Callback().Delete().Before("gorm:delete").Register("gosqlx:validate", validate)
db.Callback().Row().Before("gorm:row").Register("gosqlx:validate", validate)

Acceptance Criteria

  • GORM plugin implementing gorm.Plugin interface
  • database/sql ValidatingDB wrapper
  • All 4 DML operations covered (query, create, update, delete)
  • BlockOnError and LogOnly modes
  • LintRules selection (run only specific rules in hooks)
  • Zero overhead path when all rules pass (fast path)
  • Tests with real GORM DB (in-memory SQLite)
  • Example in examples/gorm-integration/
  • Benchmark: <500μs overhead per query validation

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium priorityenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions