formatContext formats the SQL context with position indicator Shows up to 3 lines: 1 line before, the error line, and 1 line after
()
| 234 | // formatContext formats the SQL context with position indicator |
| 235 | // Shows up to 3 lines: 1 line before, the error line, and 1 line after |
| 236 | func (e *Error) formatContext() string { |
| 237 | if e.Context == nil || e.Context.SQL == "" { |
| 238 | return "" |
| 239 | } |
| 240 | |
| 241 | var sb strings.Builder |
| 242 | lines := strings.Split(e.Context.SQL, "\n") |
| 243 | |
| 244 | if e.Location.Line <= 0 || e.Location.Line > len(lines) { |
| 245 | return "" |
| 246 | } |
| 247 | |
| 248 | errorLineNum := e.Location.Line |
| 249 | |
| 250 | // Calculate line number width for alignment (minimum 2 digits) |
| 251 | maxLineNum := errorLineNum + 1 |
| 252 | if maxLineNum > len(lines) { |
| 253 | maxLineNum = len(lines) |
| 254 | } |
| 255 | lineNumWidth := len(fmt.Sprintf("%d", maxLineNum)) |
| 256 | if lineNumWidth < 2 { |
| 257 | lineNumWidth = 2 |
| 258 | } |
| 259 | |
| 260 | sb.WriteString("\n") |
| 261 | |
| 262 | // Show line before (if exists) |
| 263 | if errorLineNum > 1 { |
| 264 | lineNum := errorLineNum - 1 |
| 265 | line := lines[lineNum-1] |
| 266 | sb.WriteString(fmt.Sprintf(" %*d | %s\n", lineNumWidth, lineNum, line)) |
| 267 | } |
| 268 | |
| 269 | // Show error line |
| 270 | line := lines[errorLineNum-1] |
| 271 | sb.WriteString(fmt.Sprintf(" %*d | %s\n", lineNumWidth, errorLineNum, line)) |
| 272 | |
| 273 | // Add position indicator (^) |
| 274 | if e.Location.Column > 0 { |
| 275 | // Account for line number prefix |
| 276 | prefix := fmt.Sprintf(" %*d | ", lineNumWidth, errorLineNum) |
| 277 | spaces := strings.Repeat(" ", len(prefix)+e.Location.Column-1) |
| 278 | highlight := "^" |
| 279 | if e.Context.HighlightLen > 1 { |
| 280 | highlight = strings.Repeat("^", e.Context.HighlightLen) |
| 281 | } |
| 282 | sb.WriteString(spaces + highlight + "\n") |
| 283 | } |
| 284 | |
| 285 | // Show line after (if exists) |
| 286 | if errorLineNum < len(lines) { |
| 287 | lineNum := errorLineNum + 1 |
| 288 | line := lines[lineNum-1] |
| 289 | sb.WriteString(fmt.Sprintf(" %*d | %s", lineNumWidth, lineNum, line)) |
| 290 | } |
| 291 | |
| 292 | return sb.String() |
| 293 | } |