Skip to content

Commit

Permalink
feat: edit geo data
Browse files Browse the repository at this point in the history
  • Loading branch information
samdyra committed Aug 15, 2024
1 parent 7bda8dd commit 6b89ddf
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
26 changes: 23 additions & 3 deletions internal/api/geo_handlers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"io"
"net/http"

"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -82,15 +83,34 @@ func (h *GeoHandler) DeleteGeoData(c *gin.Context) {

func (h *GeoHandler) EditGeoData(c *gin.Context) {
var input models.GeoDataEdit
if err := c.ShouldBindJSON(&input); err != nil {
if err := c.ShouldBind(&input); err != nil {
c.JSON(http.StatusBadRequest, errors.NewAPIError(errors.ErrInvalidInput))
return
}

oldTableName := c.Param("table_name")
username, _ := c.Get("username")

err := h.geoService.EditGeoData(oldTableName, input, username.(string))
var file io.Reader
if input.TableName != nil {
uploadedFile, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, errors.NewAPIError(errors.ErrInvalidInput))
return
}
openedFile, err := uploadedFile.Open()
if err != nil {
c.JSON(http.StatusInternalServerError, errors.NewAPIError(errors.ErrInternalServer))
return
}
defer openedFile.Close()
file = openedFile
} else if _, err := c.FormFile("file"); err == nil {
c.JSON(http.StatusBadRequest, errors.NewAPIError(errors.ErrInvalidInput))
return
}

err := h.geoService.EditGeoData(oldTableName, input, file, username.(string))
if err != nil {
switch err {
case errors.ErrNotFound:
Expand All @@ -104,4 +124,4 @@ func (h *GeoHandler) EditGeoData(c *gin.Context) {
}

c.JSON(http.StatusOK, gin.H{"message": "Geo data updated successfully"})
}
}
54 changes: 44 additions & 10 deletions internal/services/geo_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (s *GeoService) DeleteGeoData(tableName string) error {
return tx.Commit()
}

func (s *GeoService) EditGeoData(oldTableName string, data models.GeoDataEdit, username string) error {
func (s *GeoService) EditGeoData(oldTableName string, data models.GeoDataEdit, file io.Reader, username string) error {
tx, err := s.db.Beginx()
if err != nil {
return errors.ErrInternalServer
Expand All @@ -239,12 +239,6 @@ func (s *GeoService) EditGeoData(oldTableName string, data models.GeoDataEdit, u
params := []interface{}{time.Now(), username}
paramCount := 3

if data.TableName != nil {
query += fmt.Sprintf(", table_name = $%d", paramCount)
params = append(params, *data.TableName)
paramCount++
}

if data.Type != nil {
query += fmt.Sprintf(", type = $%d", paramCount)
params = append(params, *data.Type)
Expand Down Expand Up @@ -283,8 +277,8 @@ func (s *GeoService) EditGeoData(oldTableName string, data models.GeoDataEdit, u
return errors.ErrNotFound
}

// If table name was changed, rename the actual spatial data table
if data.TableName != nil && *data.TableName != oldTableName {
// If table name was changed and file is provided, rename the table and update its contents
if data.TableName != nil && *data.TableName != oldTableName && file != nil {
// Check if the new table name already exists
var exists bool
err = tx.Get(&exists, "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1)", *data.TableName)
Expand All @@ -293,7 +287,7 @@ func (s *GeoService) EditGeoData(oldTableName string, data models.GeoDataEdit, u
return errors.ErrInternalServer
}
if exists {
return errors.ErrResourceAlreadyExists
return errors.ErrTableAlreadyExists
}

// Rename the spatial data table
Expand All @@ -304,6 +298,46 @@ func (s *GeoService) EditGeoData(oldTableName string, data models.GeoDataEdit, u
}

log.Printf("Renamed spatial data table from %s to %s", oldTableName, *data.TableName)

// Clear existing data from the renamed table
_, err = tx.Exec(fmt.Sprintf("TRUNCATE TABLE %s", *data.TableName))
if err != nil {
log.Printf("Error clearing data from table %s: %v", *data.TableName, err)
return errors.ErrInternalServer
}

// Read and parse the new GeoJSON file
fileBytes, err := io.ReadAll(file)
if err != nil {
return errors.ErrInvalidInput
}

fc, err := geojson.UnmarshalFeatureCollection(fileBytes)
if err != nil {
return errors.ErrInvalidInput
}

// Insert new features into the renamed table
for _, feature := range fc.Features {
geom := feature.Geometry
properties, err := json.Marshal(feature.Properties)
if err != nil {
return errors.ErrInternalServer
}

wkbData, err := wkb.Marshal(geom)
if err != nil {
return errors.ErrInternalServer
}

_, err = tx.Exec(fmt.Sprintf(`
INSERT INTO %s (geom, properties, created_by, updated_by)
VALUES (ST_GeomFromWKB($1, 4326), $2, $3, $4)
`, *data.TableName), wkbData, properties, username, username)
if err != nil {
return errors.ErrInternalServer
}
}
}

err = tx.Commit()
Expand Down

0 comments on commit 6b89ddf

Please sign in to comment.