package api import ( "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/restxlsx/restxlsx/internal/excel" "github.com/restxlsx/restxlsx/internal/logger" ) type DDLHandler struct { engine *excel.Engine log *logger.Logger } func NewDDLHandler(engine *excel.Engine, log *logger.Logger) *DDLHandler { return &DDLHandler{engine: engine, log: log} } type createSheetReq struct { Name string `json:"name"` } func (h *DDLHandler) CreateSheet(w http.ResponseWriter, r *http.Request) { var req createSheetReq if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, 400, map[string]string{"error": "invalid JSON: " + err.Error()}) return } if req.Name == "" { writeJSON(w, 400, map[string]string{"error": "name is required"}) return } h.engine.Lock() defer h.engine.Unlock() if err := h.engine.CreateSheet(req.Name); err != nil { writeJSON(w, 409, map[string]string{"error": err.Error()}) return } if err := h.engine.Flush(); err != nil { writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()}) return } writeJSON(w, 201, map[string]any{"sheet": req.Name, "status": "created"}) } func (h *DDLHandler) DropSheet(w http.ResponseWriter, r *http.Request) { sheet := chi.URLParam(r, "sheet") if sheet == "" { writeJSON(w, 400, map[string]string{"error": "sheet name required"}) return } h.engine.Lock() defer h.engine.Unlock() if err := h.engine.DropSheet(sheet); err != nil { writeJSON(w, 404, map[string]string{"error": err.Error()}) return } if err := h.engine.Flush(); err != nil { writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()}) return } writeJSON(w, 200, map[string]any{"sheet": sheet, "status": "deleted"}) } type createTableReq struct { Sheet string `json:"sheet"` Name string `json:"name"` Columns []string `json:"columns"` } func (h *DDLHandler) CreateTable(w http.ResponseWriter, r *http.Request) { var req createTableReq if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, 400, map[string]string{"error": "invalid JSON: " + err.Error()}) return } if req.Name == "" || req.Sheet == "" || len(req.Columns) == 0 { writeJSON(w, 400, map[string]string{"error": "sheet, name, and columns are required"}) return } h.engine.Lock() defer h.engine.Unlock() if h.engine.GetTable(req.Sheet) == nil { if err := h.engine.CreateSheet(req.Sheet); err != nil { writeJSON(w, 409, map[string]string{"error": err.Error()}) return } } if err := h.engine.CreateTable(req.Sheet, req.Columns, []map[string]any{}); err != nil { writeJSON(w, 409, map[string]string{"error": err.Error()}) return } t := h.engine.GetTable(req.Sheet) t.Name = req.Name h.engine.Tables[req.Name] = t delete(h.engine.Tables, req.Sheet) if err := h.engine.Flush(); err != nil { writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()}) return } writeJSON(w, 201, map[string]any{"table": req.Name, "sheet": req.Sheet, "columns": req.Columns, "status": "created"}) } func (h *DDLHandler) DropTable(w http.ResponseWriter, r *http.Request) { table := chi.URLParam(r, "table") if table == "" { writeJSON(w, 400, map[string]string{"error": "table name required"}) return } h.engine.Lock() defer h.engine.Unlock() if err := h.engine.DropTable(table); err != nil { writeJSON(w, 404, map[string]string{"error": err.Error()}) return } if err := h.engine.Flush(); err != nil { writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()}) return } writeJSON(w, 200, map[string]any{"table": table, "status": "deleted"}) }