initial commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/restxlsx/restxlsx/internal/excel"
|
||||
"github.com/restxlsx/restxlsx/internal/logger"
|
||||
)
|
||||
|
||||
type RestAPI struct {
|
||||
engine *excel.Engine
|
||||
log *logger.Logger
|
||||
}
|
||||
|
||||
func NewRestAPI(engine *excel.Engine, log *logger.Logger) *RestAPI {
|
||||
return &RestAPI{engine: engine, log: log}
|
||||
}
|
||||
|
||||
func (h *RestAPI) ListTables(w http.ResponseWriter, r *http.Request) {
|
||||
h.engine.Lock()
|
||||
tables := h.engine.ListTables()
|
||||
h.engine.Unlock()
|
||||
writeJSON(w, 200, map[string][]string{"tables": tables})
|
||||
}
|
||||
|
||||
func (h *RestAPI) ListRecords(w http.ResponseWriter, r *http.Request) {
|
||||
table := chi.URLParam(r, "table")
|
||||
h.engine.Lock()
|
||||
t := h.engine.GetTable(table)
|
||||
if t == nil {
|
||||
h.engine.Unlock()
|
||||
writeJSON(w, 404, map[string]string{"error": "table not found"})
|
||||
return
|
||||
}
|
||||
rows := t.Rows
|
||||
h.engine.Unlock()
|
||||
writeJSON(w, 200, rows)
|
||||
}
|
||||
|
||||
func (h *RestAPI) GetRecord(w http.ResponseWriter, r *http.Request) {
|
||||
table := chi.URLParam(r, "table")
|
||||
id := chi.URLParam(r, "id")
|
||||
h.engine.Lock()
|
||||
t := h.engine.GetTable(table)
|
||||
if t == nil {
|
||||
h.engine.Unlock()
|
||||
writeJSON(w, 404, map[string]string{"error": "table not found"})
|
||||
return
|
||||
}
|
||||
idCol := h.engine.IDColumn(table)
|
||||
for _, row := range t.Rows {
|
||||
if fmt.Sprintf("%v", row[idCol]) == id {
|
||||
h.engine.Unlock()
|
||||
writeJSON(w, 200, row)
|
||||
return
|
||||
}
|
||||
}
|
||||
h.engine.Unlock()
|
||||
writeJSON(w, 404, map[string]string{"error": "record not found"})
|
||||
}
|
||||
|
||||
func (h *RestAPI) CreateRecord(w http.ResponseWriter, r *http.Request) {
|
||||
table := chi.URLParam(r, "table")
|
||||
|
||||
var rec map[string]any
|
||||
if err := json.NewDecoder(r.Body).Decode(&rec); err != nil {
|
||||
writeJSON(w, 400, map[string]string{"error": "invalid JSON: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.engine.Lock()
|
||||
defer h.engine.Unlock()
|
||||
t := h.engine.GetTable(table)
|
||||
if t == nil {
|
||||
writeJSON(w, 404, map[string]string{"error": "table not found"})
|
||||
return
|
||||
}
|
||||
|
||||
idCol := h.engine.IDColumn(table)
|
||||
if idCol != "" {
|
||||
if _, ok := rec[idCol]; !ok {
|
||||
rec[idCol] = len(t.Rows) + 1
|
||||
}
|
||||
}
|
||||
|
||||
t.Rows = append(t.Rows, rec)
|
||||
if err := h.engine.Flush(); err != nil {
|
||||
writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()})
|
||||
return
|
||||
}
|
||||
writeJSON(w, 201, rec)
|
||||
}
|
||||
|
||||
func (h *RestAPI) UpdateRecord(w http.ResponseWriter, r *http.Request) {
|
||||
table := chi.URLParam(r, "table")
|
||||
id := chi.URLParam(r, "id")
|
||||
|
||||
var rec map[string]any
|
||||
if err := json.NewDecoder(r.Body).Decode(&rec); err != nil {
|
||||
writeJSON(w, 400, map[string]string{"error": "invalid JSON: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.engine.Lock()
|
||||
defer h.engine.Unlock()
|
||||
t := h.engine.GetTable(table)
|
||||
if t == nil {
|
||||
writeJSON(w, 404, map[string]string{"error": "table not found"})
|
||||
return
|
||||
}
|
||||
|
||||
idCol := h.engine.IDColumn(table)
|
||||
for i, row := range t.Rows {
|
||||
if fmt.Sprintf("%v", row[idCol]) == id {
|
||||
for k, v := range rec {
|
||||
t.Rows[i][k] = v
|
||||
}
|
||||
if err := h.engine.Flush(); err != nil {
|
||||
writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()})
|
||||
return
|
||||
}
|
||||
writeJSON(w, 200, t.Rows[i])
|
||||
return
|
||||
}
|
||||
}
|
||||
writeJSON(w, 404, map[string]string{"error": "record not found"})
|
||||
}
|
||||
|
||||
func (h *RestAPI) DeleteRecord(w http.ResponseWriter, r *http.Request) {
|
||||
table := chi.URLParam(r, "table")
|
||||
id := chi.URLParam(r, "id")
|
||||
h.engine.Lock()
|
||||
defer h.engine.Unlock()
|
||||
t := h.engine.GetTable(table)
|
||||
if t == nil {
|
||||
writeJSON(w, 404, map[string]string{"error": "table not found"})
|
||||
return
|
||||
}
|
||||
|
||||
idCol := h.engine.IDColumn(table)
|
||||
for i, row := range t.Rows {
|
||||
if fmt.Sprintf("%v", row[idCol]) == id {
|
||||
t.Rows = append(t.Rows[:i], t.Rows[i+1:]...)
|
||||
if err := h.engine.Flush(); err != nil {
|
||||
writeJSON(w, 503, map[string]string{"error": "flush failed: " + err.Error()})
|
||||
return
|
||||
}
|
||||
writeJSON(w, 204, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
writeJSON(w, 404, map[string]string{"error": "record not found"})
|
||||
}
|
||||
|
||||
type responseWriter struct {
|
||||
http.ResponseWriter
|
||||
status int
|
||||
}
|
||||
|
||||
func (rw *responseWriter) WriteHeader(code int) {
|
||||
rw.status = code
|
||||
rw.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
func writeJSON(w http.ResponseWriter, status int, data any) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
if data != nil {
|
||||
json.NewEncoder(w).Encode(data)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user