go-gorm / go-gorm/cli

perf: reuse NamingStrategy and fix fragile param counting in SQL template renderer

Open
#59 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
108
Forks
15
PR merge metrics
No merged PRs in 30d

Description

## Summary

Two per-field inefficiencies in the code generation hot path:

### 1. `schema.NamingStrategy` created per field

`utils.go:153-162` — `generateDBName` is called for every exported field of every struct:

```go
func generateDBName(fieldName, gormTag string) string {
// ...
ns := schema.NamingStrategy{IdentifierMaxLength: 64}
return ns.ColumnName("", fieldName)
}
```

`NamingStrategy` is stateless — a single package-level instance suffices:

```go
var namingStrategy = schema.NamingStrategy{IdentifierMaxLength: 64}
```

### 2. Param counting in `RenderSQLTemplate` is fragile

`sqlparser.go:329-343` — After building the AST, the renderer estimates param count by:
1. Splitting emitted Go code into lines
2. Counting commas in `_params = append(_params, ...)` lines
3. Detecting `for` loops and multiplying by 4

```go
for _, line := range strings.Split(code, "\n") {
if strings.Index(code, "\tfor ") > 0 {
baseCount = 4
}
if strings.Contains(line, "_params = append(_params") {
count += strings.Count(line, ",") * baseCount
}
}
```

**Problems:**
- Commas inside string literals (e.g. `CONCAT("a, b")`) cause overcounting
- The `for` detection (`strings.Index(code, "\tfor ") > 0`) checks the entire code block, not the current line — once one `for` is found, all subsequent params are multiplied by 4
- The 4× multiplier is a hardcoded guess

**Fix:** Track param count during AST construction. Each `TextNode.Emit` already knows how many params it appends — return that count alongside the code string. `ForNode` and `IfNode` can sum their children's counts.

## Expected Impact

Minor per-field improvement × thousands of fields = meaningful reduction in generation time. The param counting fix also prevents incorrect `_params` slice preallocation (which currently causes either overallocation or underallocation depending on the code).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.