feat: abstracción DB multi-engine — CRUD genérico y openers para SQLite, Postgres, ClickHouse, DuckDB
Funciones Go con interfaz unificada para operaciones DB: open, close, create_table, exec, query, insert_row, insert_batch. Openers específicos por engine. Tipo DBConfig para configuración común. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package infra
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var validIdentifier = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)
|
||||
|
||||
// DBCreateTable executes CREATE TABLE IF NOT EXISTS for the given table with
|
||||
// the provided column definitions. Each element of columns should be a full
|
||||
// SQL column definition, e.g. "id INTEGER PRIMARY KEY" or "name TEXT NOT NULL".
|
||||
// Returns an error if the table name contains invalid characters.
|
||||
func DBCreateTable(db *sql.DB, table string, columns []string) error {
|
||||
if !validIdentifier.MatchString(table) {
|
||||
return fmt.Errorf("db_create_table: invalid table name %q (only alphanumeric and underscore allowed)", table)
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return fmt.Errorf("db_create_table: at least one column definition required")
|
||||
}
|
||||
query := fmt.Sprintf(
|
||||
"CREATE TABLE IF NOT EXISTS %s (%s)",
|
||||
table,
|
||||
strings.Join(columns, ", "),
|
||||
)
|
||||
if _, err := db.Exec(query); err != nil {
|
||||
return fmt.Errorf("db_create_table %q: %w", table, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user