Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// mysqlCol returns a quoted column name if present, otherwise a SQL literal/expression fallback.
|
||||
func mysqlCol(ctx context.Context, db *sql.DB, table, column, fallbackExpr string) string {
|
||||
if mysqlColumnExists(ctx, db, table, column) {
|
||||
q, err := quoteMySQLIdent(column)
|
||||
if err != nil {
|
||||
return fallbackExpr
|
||||
}
|
||||
return q
|
||||
}
|
||||
return fallbackExpr
|
||||
}
|
||||
|
||||
// mysqlCoalesce returns COALESCE(column, fallback) when column exists, else fallback alone.
|
||||
func mysqlCoalesce(ctx context.Context, db *sql.DB, table, column, fallbackExpr string) string {
|
||||
if mysqlColumnExists(ctx, db, table, column) {
|
||||
q, err := quoteMySQLIdent(column)
|
||||
if err != nil {
|
||||
return fallbackExpr
|
||||
}
|
||||
return fmt.Sprintf("COALESCE(%s, %s)", q, fallbackExpr)
|
||||
}
|
||||
return fallbackExpr
|
||||
}
|
||||
|
||||
// mysqlSelectList builds "SELECT a, b, ..." from expressions (already resolved).
|
||||
func mysqlSelectList(exprs ...string) string {
|
||||
return "SELECT " + strings.Join(exprs, ", ")
|
||||
}
|
||||
|
||||
// scanIntish scans MySQL INT/DECIMAL/string numeric values into an int.
|
||||
func scanIntish(v any) int {
|
||||
switch x := v.(type) {
|
||||
case int64:
|
||||
return int(x)
|
||||
case int32:
|
||||
return int(x)
|
||||
case float64:
|
||||
return int(x)
|
||||
case []byte:
|
||||
var n float64
|
||||
if _, err := fmt.Sscanf(string(x), "%f", &n); err == nil {
|
||||
return int(n)
|
||||
}
|
||||
case string:
|
||||
var n float64
|
||||
if _, err := fmt.Sscanf(x, "%f", &n); err == nil {
|
||||
return int(n)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// queryFirstOK tries queries in order until one succeeds (for column-shape fallbacks).
|
||||
func queryFirstOK(ctx context.Context, db *sql.DB, queries ...string) (*sql.Rows, error) {
|
||||
var last error
|
||||
for _, q := range queries {
|
||||
rows, err := db.QueryContext(ctx, q)
|
||||
if err == nil {
|
||||
return rows, nil
|
||||
}
|
||||
last = err
|
||||
}
|
||||
if last == nil {
|
||||
return nil, fmt.Errorf("no queries provided")
|
||||
}
|
||||
return nil, last
|
||||
}
|
||||
Reference in New Issue
Block a user