-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #78 from fabiante/feat/gorm-rewrite
- Loading branch information
Showing
12 changed files
with
256 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package api | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/fabiante/persurl/api/res" | ||
"github.com/fabiante/persurl/app" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
func (s *Server) SavePURL(ctx *gin.Context) { | ||
domain := ctx.Param("domain") | ||
name := ctx.Param("name") | ||
|
||
var req res.SavePURL | ||
if err := ctx.BindJSON(&req); err != nil { | ||
ctx.Abort() | ||
return | ||
} | ||
|
||
err := s.admin.SavePURL(domain, name, req.Target) | ||
switch true { | ||
case err == nil: | ||
break | ||
case errors.Is(err, app.ErrBadRequest): | ||
respondWithError(ctx, http.StatusBadRequest, err) | ||
default: | ||
respondWithError(ctx, http.StatusInternalServerError, err) | ||
} | ||
|
||
ctx.JSON(http.StatusOK, res.NewSavePURLResponse(fmt.Sprintf("/r/%s/%s", domain, name))) | ||
} | ||
|
||
func (s *Server) CreateDomain(ctx *gin.Context) { | ||
domain := ctx.Param("domain") | ||
|
||
err := s.admin.CreateDomain(domain) | ||
switch true { | ||
case err == nil: | ||
ctx.Status(http.StatusNoContent) | ||
case errors.Is(err, app.ErrBadRequest): | ||
respondWithError(ctx, http.StatusBadRequest, err) | ||
default: | ||
respondWithError(ctx, http.StatusInternalServerError, err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package models | ||
|
||
import "gorm.io/gorm" | ||
|
||
type Domain struct { | ||
gorm.Model | ||
|
||
Name string | ||
|
||
PURLs []*PURL `gorm:"foreignKey:DomainID"` | ||
} | ||
|
||
type PURL struct { | ||
gorm.Model | ||
|
||
DomainID uint | ||
|
||
Name string | ||
Target string | ||
} | ||
|
||
func (P PURL) TableName() string { | ||
return "purls" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package app | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/fabiante/persurl/app/models" | ||
"github.com/lib/pq" | ||
"gorm.io/gorm" | ||
) | ||
|
||
type service struct { | ||
db *gorm.DB | ||
} | ||
|
||
func NewService(db *gorm.DB) ServiceInterface { | ||
return &service{db: db} | ||
} | ||
|
||
func (s *service) Resolve(domain, name string) (string, error) { | ||
purl := &models.PURL{} | ||
|
||
err := s.db.Model(&models.PURL{}). | ||
Joins("join domains on domains.id = purls.domain_id"). | ||
Where("domains.name = ?", domain). | ||
Where("purls.name = ?", name). | ||
Take(purl).Error | ||
|
||
switch { | ||
case err == nil: | ||
return purl.Target, nil | ||
case errors.Is(err, gorm.ErrRecordNotFound): | ||
return "", ErrNotFound | ||
default: | ||
return "", mapDBError(err) | ||
} | ||
} | ||
|
||
func (s *service) CreateDomain(name string) error { | ||
domain := &models.Domain{ | ||
Name: name, | ||
} | ||
|
||
err := s.db.Create(domain).Error | ||
|
||
if err != nil { | ||
return mapDBError(err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *service) SavePURL(domainName, name, target string) error { | ||
domain := &models.Domain{} | ||
|
||
// get domain | ||
{ | ||
err := s.db.Where(&models.Domain{Name: domainName}).Take(domain).Error | ||
if err != nil { | ||
switch { | ||
case err == nil: | ||
break | ||
case errors.Is(err, gorm.ErrRecordNotFound): | ||
return fmt.Errorf("%w: domain does not exist", ErrBadRequest) | ||
default: | ||
return mapDBError(err) | ||
} | ||
} | ||
} | ||
|
||
// save purl | ||
{ | ||
purl := &models.PURL{ | ||
DomainID: domain.ID, | ||
Name: name, | ||
Target: target, | ||
} | ||
|
||
err := s.db.FirstOrCreate(purl).Error | ||
|
||
if err != nil { | ||
return mapDBError(err) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
const ( | ||
pgErrUniqueKeyViolation = "23505" | ||
) | ||
|
||
func mapDBError(err error) error { | ||
var serr *pq.Error | ||
if !errors.As(err, &serr) { | ||
return err | ||
} | ||
|
||
// Error codes | ||
// SQLite: https://www.sqlite.org/rescode.html | ||
// Postgres: http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html | ||
|
||
code := serr.Code | ||
switch code { | ||
case pgErrUniqueKeyViolation: | ||
return fmt.Errorf("%w: %s", ErrBadRequest, err) | ||
default: | ||
return fmt.Errorf("unexpected error: %w", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.