Files
OwOrganizer/backend/object.go
T
2026-07-16 19:24:39 -07:00

198 lines
4.9 KiB
Go

package main
import (
"database/sql"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// Object represents a row in the objects table.
type Object struct {
ObjectID string
UserID string
ObjectData string
}
// CreateObject inserts a new object into the objects table.
func CreateObject(objectID, userID, objectData string) error {
_, err := DB.Exec(
"INSERT INTO objects (objectId, userId, objectData) VALUES (?, ?, ?)",
objectID, userID, objectData,
)
if err != nil {
return fmt.Errorf("failed to create object: %w", err)
}
return nil
}
// GetObject retrieves an object by ID.
func GetObject(objectID string) (Object, error) {
var obj Object
err := DB.QueryRow(
"SELECT objectId, userId, objectData FROM objects WHERE objectId = ?",
objectID,
).Scan(&obj.ObjectID, &obj.UserID, &obj.ObjectData)
if err != nil {
if err == sql.ErrNoRows {
return Object{}, fmt.Errorf("object not found")
}
return Object{}, fmt.Errorf("failed to get object: %w", err)
}
return obj, nil
}
// GetObjectsByUser retrieves all objects belonging to a user.
func GetObjectsByUser(userID string) ([]Object, error) {
rows, err := DB.Query(
"SELECT objectId, userId, objectData FROM objects WHERE userId = ?",
userID,
)
if err != nil {
return nil, fmt.Errorf("failed to query objects: %w", err)
}
defer rows.Close()
var objects []Object
for rows.Next() {
var obj Object
if err := rows.Scan(&obj.ObjectID, &obj.UserID, &obj.ObjectData); err != nil {
return nil, fmt.Errorf("failed to scan object: %w", err)
}
objects = append(objects, obj)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("failed to iterate objects: %w", err)
}
return objects, nil
}
// UpdateObject updates the objectData for an object.
func UpdateObject(objectID, objectData string) error {
result, err := DB.Exec(
"UPDATE objects SET objectData = ? WHERE objectId = ?",
objectData, objectID,
)
if err != nil {
return fmt.Errorf("failed to update object: %w", err)
}
rows, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("failed to check update result: %w", err)
}
if rows == 0 {
return fmt.Errorf("object not found")
}
return nil
}
// DeleteObject removes an object by ID.
func DeleteObject(objectID string) error {
result, err := DB.Exec("DELETE FROM objects WHERE objectId = ?", objectID)
if err != nil {
return fmt.Errorf("failed to delete object: %w", err)
}
rows, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("failed to check delete result: %w", err)
}
if rows == 0 {
return fmt.Errorf("object not found")
}
return nil
}
// createObjectRequest is the expected body for POST /objects.
type createObjectRequest struct {
ObjectID string `json:"objectId"`
UserID string `json:"userId" binding:"required"`
ObjectData string `json:"objectData" binding:"required"`
}
func createObjectHandler(c *gin.Context) {
var req createObjectRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
objectID := req.ObjectID
if objectID == "" {
objectID = uuid.NewString()
}
if err := CreateObject(objectID, req.UserID, req.ObjectData); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{"status": "created", "objectId": objectID})
}
func getObjectHandler(c *gin.Context) {
id := c.Param("id")
obj, err := GetObject(id)
if err != nil {
if err.Error() == "object not found" {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, obj)
}
func getObjectsByUserHandler(c *gin.Context) {
id := c.Param("id")
objects, err := GetObjectsByUser(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, objects)
}
// updateObjectRequest is the expected body for PUT /objects/:id.
type updateObjectRequest struct {
ObjectData string `json:"objectData" binding:"required"`
}
func updateObjectHandler(c *gin.Context) {
id := c.Param("id")
var req updateObjectRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := UpdateObject(id, req.ObjectData); err != nil {
if err.Error() == "object not found" {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "updated"})
}
func deleteObjectHandler(c *gin.Context) {
id := c.Param("id")
if err := DeleteObject(id); err != nil {
if err.Error() == "object not found" {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "deleted"})
}