Files
restxlsx/internal/api/ddl.go
T
2026-06-10 13:01:57 +02:00

128 lines
3.6 KiB
Go

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"})
}