4c88adc183
Anade los tipos CRUDResource, CRUDField, CRUDListParams y CRUDListResult que modelan un recurso CRUD sobre SQLite, junto con dos funciones puras: - crud_define_resource valida nombre, tabla y campos (tipos SQLite validos, nombres reservados, duplicados) antes de retornar el CRUDResource. - crud_generate_table_sql genera el DDL CREATE TABLE IF NOT EXISTS con id TEXT PRIMARY KEY, timestamps estandar y, si aplica, deleted_at para soft delete. Primera capa de 0021 — el resto (handlers + registro de rutas) se apoya sobre estas estructuras.
41 lines
1.5 KiB
Go
41 lines
1.5 KiB
Go
package infra
|
|
|
|
import "fmt"
|
|
|
|
// CRUDDefineResource construye un CRUDResource validando que el nombre no este vacio,
|
|
// que haya al menos un campo y que todos los tipos de los campos sean validos
|
|
// (TEXT, INTEGER, REAL, BLOB). Es pura — solo valida y devuelve la estructura.
|
|
func CRUDDefineResource(name string, table string, fields []CRUDField, softDelete bool) (CRUDResource, error) {
|
|
if name == "" {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: name must not be empty")
|
|
}
|
|
if table == "" {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: table must not be empty")
|
|
}
|
|
if len(fields) == 0 {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: must have at least one field")
|
|
}
|
|
seen := make(map[string]bool, len(fields))
|
|
for _, f := range fields {
|
|
if f.Name == "" {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: field name must not be empty")
|
|
}
|
|
if f.Name == "id" || f.Name == "created_at" || f.Name == "updated_at" || f.Name == "deleted_at" {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: field name %q is reserved", f.Name)
|
|
}
|
|
if seen[f.Name] {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: duplicate field name %q", f.Name)
|
|
}
|
|
seen[f.Name] = true
|
|
if !isValidCRUDType(f.Type) {
|
|
return CRUDResource{}, fmt.Errorf("crud_define_resource: invalid type %q for field %q (must be TEXT, INTEGER, REAL or BLOB)", f.Type, f.Name)
|
|
}
|
|
}
|
|
return CRUDResource{
|
|
Name: name,
|
|
Table: table,
|
|
Fields: fields,
|
|
SoftDelete: softDelete,
|
|
}, nil
|
|
}
|