sum changes

master
Jasper Levin Spahl 3 years ago
parent 43d05ce727
commit 0c491a6500

@ -1,11 +1,11 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Launch Package", "name": "Launch Package",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "auto", "mode": "auto",
"program": "." "program": "."
} }
] ]
} }

@ -1,11 +1,11 @@
{ {
"sqltools.connections": [ "sqltools.connections": [
{ {
"previewLimit": 50, "previewLimit": 50,
"driver": "SQLite", "driver": "SQLite",
"name": "devdb", "name": "devdb",
"database": "${workspaceFolder}/dev.db" "database": "${workspaceFolder}/dev.db"
} }
], ],
"sqltools.useNodeRuntime": true "sqltools.useNodeRuntime": true
} }

BIN
dev.db

Binary file not shown.

@ -4,7 +4,7 @@ go 1.15
require ( require (
github.com/gin-gonic/gin v1.7.7 github.com/gin-gonic/gin v1.7.7
github.com/mattn/go-sqlite3 v1.14.10 github.com/mattn/go-sqlite3 v1.14.10 // indirect
gorm.io/driver/sqlite v1.2.6 gorm.io/driver/sqlite v1.2.6
gorm.io/gorm v1.22.5 gorm.io/gorm v1.22.5
) )

@ -1,11 +1,9 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -21,7 +19,6 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
@ -30,16 +27,12 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk=
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@ -56,12 +49,10 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4= gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY= gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=

@ -1,152 +1,153 @@
package api package api
import ( import (
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
"dymatrix.de/jspahl/todo/internal/types" "dymatrix.de/jspahl/todo/internal/types"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
type ItemDTO struct { type ItemDTO struct {
id int id int
message string message string
} }
func (item ItemDTO) GetId() int { func (item ItemDTO) GetId() int {
return item.id return item.id
} }
func (item ItemDTO) GetMessage() string { func (item ItemDTO) GetMessage() string {
return item.message return item.message
} }
type UserDTO struct { type UserDTO struct {
id int id int
username string username string
} }
func (user UserDTO) GetId() int { func (user UserDTO) GetId() int {
return user.id return user.id
} }
func (user UserDTO) GetUsername() string { func (user UserDTO) GetUsername() string {
return user.username return user.username
} }
func ItemToDTO(item types.IItem) ItemDTO { func ItemToDTO(item types.IItem) ItemDTO {
var itemDto = ItemDTO{} var itemDto = ItemDTO{}
itemDto.id = item.GetId() itemDto.id = item.GetId()
itemDto.message = item.GetMessage() itemDto.message = item.GetMessage()
return itemDto return itemDto
} }
func ItemsToDTOs(items []types.IItem) []ItemDTO { func ItemsToDTOs(items []types.IItem) []ItemDTO {
var itemDtos []ItemDTO var itemDtos []ItemDTO
for _, item := range items { for _, item := range items {
itemDtos = append(itemDtos, ItemToDTO(item)) itemDtos = append(itemDtos, ItemToDTO(item))
} }
return itemDtos return itemDtos
} }
func RegisterRoutes(router *gin.RouterGroup, prov types.IPersitenceProvider) { func RegisterRoutes(router *gin.RouterGroup, prov types.IPersitenceProvider) {
router.GET("/item", func(c *gin.Context) { router.GET("/item", func(c *gin.Context) {
items, err := prov.GetAllItems() items, err := prov.GetAllItems()
if err != nil { if err != nil {
c.String(http.StatusInternalServerError, err.Error()) c.String(http.StatusInternalServerError, err.Error())
return return
} }
itemDTOs := ItemsToDTOs(items) itemDTOs := ItemsToDTOs(items)
c.JSON(http.StatusOK, itemDTOs) c.JSON(http.StatusOK, itemDTOs)
}) })
router.GET("/item/:id", func(c *gin.Context) { router.GET("/item/:id", func(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id")) id, err := strconv.Atoi(c.Param("id"))
if err != nil { if err != nil {
c.String(http.StatusBadRequest, err.Error()) c.String(http.StatusBadRequest, err.Error())
} }
log.Println(id) log.Println(id)
item, err := prov.GetItem(id) item, err := prov.GetItem(id)
if err != nil { if err != nil {
c.String(http.StatusInternalServerError, err.Error()) c.String(http.StatusInternalServerError, err.Error())
} }
c.JSON(http.StatusOK, ItemToDTO(item)) c.JSON(http.StatusOK, ItemToDTO(item))
}) })
router.GET("/itemByUser/:id", func(c *gin.Context) { router.GET("/itemByUser/:id", func(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id")) id, err := strconv.Atoi(c.Param("id"))
if err != nil { if err != nil {
c.String(404, err.Error()) c.String(404, err.Error())
return return
} }
items, err := prov.GetItemByUser(UserDTO{id: id}) items, err := prov.GetItemByUser(UserDTO{id: id})
if err != nil { if err != nil {
c.String(http.StatusInternalServerError, err.Error()) c.String(http.StatusInternalServerError, err.Error())
return return
} }
c.JSON(http.StatusOK, ItemsToDTOs(items)) c.JSON(http.StatusOK, ItemsToDTOs(items))
}) })
router.POST("/item", func(c *gin.Context) { router.POST("/item", func(c *gin.Context) {
var item struct { var item struct {
message string message string
} }
if err := c.BindJSON(&item); err != nil { if err := c.BindJSON(&item); err != nil {
c.String(http.StatusBadRequest, err.Error()) c.String(http.StatusBadRequest, err.Error())
} return
prov.CreateItem(ItemDTO{message: item.message}) }
c.Status(200) prov.CreateItem(ItemDTO{message: item.message})
}) c.Status(200)
router.PUT("/item", func(c *gin.Context) { })
var item ItemDTO router.PUT("/item", func(c *gin.Context) {
if err := c.BindJSON(&item); err != nil { var item ItemDTO
c.String(http.StatusBadRequest, err.Error()) if err := c.BindJSON(&item); err != nil {
return c.String(http.StatusBadRequest, err.Error())
} return
if err := prov.UpdateItem(item); err != nil { }
c.String(http.StatusInternalServerError, err.Error()) if err := prov.UpdateItem(item); err != nil {
return c.String(http.StatusInternalServerError, err.Error())
} return
c.Status(200) }
}) c.Status(200)
router.DELETE("/item/:id", func(c *gin.Context) { })
id, err := strconv.Atoi(c.Param("id")) router.DELETE("/item/:id", func(c *gin.Context) {
if err != nil { id, err := strconv.Atoi(c.Param("id"))
c.String(404, err.Error()) if err != nil {
return c.String(404, err.Error())
} return
if err := prov.DeleteItem(ItemDTO{id: id}); err != nil { }
c.String(404, err.Error()) if err := prov.DeleteItem(ItemDTO{id: id}); err != nil {
return c.String(404, err.Error())
} return
c.Status(200) }
}) c.Status(200)
router.GET("/link/:itemId/:userId", func(c *gin.Context) { })
itemId, err := strconv.Atoi(c.Param("itemId")) router.GET("/link/:itemId/:userId", func(c *gin.Context) {
if err != nil { itemId, err := strconv.Atoi(c.Param("itemId"))
c.String(404, err.Error()) if err != nil {
return c.String(404, err.Error())
} return
userId, err := strconv.Atoi(c.Param("userId")) }
if err != nil { userId, err := strconv.Atoi(c.Param("userId"))
c.String(404, err.Error()) if err != nil {
return c.String(404, err.Error())
} return
if err := prov.Link(UserDTO{id: userId}, ItemDTO{id: itemId}); err != nil { }
c.String(404, err.Error()) if err := prov.Link(UserDTO{id: userId}, ItemDTO{id: itemId}); err != nil {
return c.String(404, err.Error())
} return
c.Status(200) }
}) c.Status(200)
router.POST("/user", func(c *gin.Context) { })
var user struct { router.POST("/user", func(c *gin.Context) {
username string var user struct {
} username string
if err := c.BindJSON(&user); err != nil { }
c.String(http.StatusBadRequest, err.Error()) if err := c.BindJSON(&user); err != nil {
return c.String(http.StatusBadRequest, err.Error())
} return
id, err := prov.CreateUser(UserDTO{username: user.username}) }
if err != nil { id, err := prov.CreateUser(UserDTO{username: user.username})
c.String(404, err.Error()) if err != nil {
} c.String(404, err.Error())
c.JSON(200, &gin.H{ }
"id": id, c.JSON(200, &gin.H{
}) "id": id,
}) })
} })
}

@ -1,100 +1,102 @@
package implementations package implementations
import ( import (
"errors" "errors"
"log"
"dymatrix.de/jspahl/todo/internal/types"
) "dymatrix.de/jspahl/todo/internal/types"
)
type Item struct {
id int type Item struct {
message string id int
deleted bool message string
} deleted bool
}
func (item Item) GetId() int {
return item.id func (item Item) GetId() int {
} return item.id
func (item Item) GetMessage() string { }
return item.message func (item Item) GetMessage() string {
} return item.message
}
type MemoryProvider struct {
index int type MemoryProvider struct {
items []Item index int
itemsByUsers [][]*Item items []Item
} itemsByUsers [][]*Item
}
func (prov MemoryProvider) CreateItem(item types.IItem) error {
storedItem := Item{id: prov.index, message: item.GetMessage(), deleted: false} func (prov MemoryProvider) CreateItem(item types.IItem) error {
prov.items = append(prov.items, storedItem) storedItem := Item{id: prov.index, message: item.GetMessage(), deleted: false}
prov.index++ prov.items = append(prov.items, storedItem)
return nil prov.index++
} return nil
}
func (prov MemoryProvider) UpdateItem(item types.IItem) error {
storedItem, err := prov.GetItemPtr(item.GetId()) func (prov MemoryProvider) UpdateItem(item types.IItem) error {
if err != nil { storedItem, err := prov.GetItemPtr(item.GetId())
return err if err != nil {
} return err
storedItem.message = item.GetMessage() }
return nil storedItem.message = item.GetMessage()
} return nil
}
func (prov MemoryProvider) GetItemPtr(id int) (*Item, error) {
for i, item := range prov.items { func (prov MemoryProvider) GetItemPtr(id int) (*Item, error) {
if item.id == id && !item.deleted { log.Printf("Getting Item Ptr for %d\n", id)
return &prov.items[i], nil for i, item := range prov.items {
} if item.id == id && !item.deleted {
} return &prov.items[i], nil
return nil, errors.New("Item not found") }
} }
return nil, errors.New("Item not found")
func (prov MemoryProvider) GetItem(id int) (types.IItem, error) { }
item, err := prov.GetItemPtr(id)
return *item, err func (prov MemoryProvider) GetItem(id int) (types.IItem, error) {
item, err := prov.GetItemPtr(id)
} return *item, err
func (prov MemoryProvider) GetItemByUser(user types.IUser) ([]types.IItem, error) { }
var items []types.IItem
for i := range prov.itemsByUsers[user.GetId()] { func (prov MemoryProvider) GetItemByUser(user types.IUser) ([]types.IItem, error) {
items = append(items, *prov.itemsByUsers[user.GetId()][i]) var items []types.IItem
} for i := range prov.itemsByUsers[user.GetId()] {
if len(items) == 0 { items = append(items, *prov.itemsByUsers[user.GetId()][i])
return items, errors.New("no items for user ") }
} if len(items) == 0 {
return items, nil return items, errors.New("no items for user ")
} }
return items, nil
func (prov MemoryProvider) GetAllItems() ([]types.IItem, error) { }
var items []types.IItem
for _, item := range prov.items { func (prov MemoryProvider) GetAllItems() ([]types.IItem, error) {
if !item.deleted { var items []types.IItem
items = append(items, item) for _, item := range prov.items {
} if !item.deleted {
} items = append(items, item)
return items, nil }
} }
return items, nil
func (prov MemoryProvider) Link(user types.IUser, item types.IItem) error { }
storedItem, err := prov.GetItemPtr(item.GetId())
if err != nil { func (prov MemoryProvider) Link(user types.IUser, item types.IItem) error {
return err storedItem, err := prov.GetItemPtr(item.GetId())
} if err != nil {
prov.itemsByUsers[user.GetId()] = append(prov.itemsByUsers[user.GetId()], storedItem) return err
return nil }
} prov.itemsByUsers[user.GetId()] = append(prov.itemsByUsers[user.GetId()], storedItem)
return nil
func (prov MemoryProvider) DeleteItem(item types.IItem) error { }
storedItem, err := prov.GetItemPtr(item.GetId())
if err != nil { func (prov MemoryProvider) DeleteItem(item types.IItem) error {
return err storedItem, err := prov.GetItemPtr(item.GetId())
} if err != nil {
storedItem.deleted = true return err
return nil }
} storedItem.deleted = true
return nil
func (prov MemoryProvider) CreateUser(user types.IUser) (int, error) { }
return prov.index, nil
} func (prov MemoryProvider) CreateUser(user types.IUser) (int, error) {
return prov.index, nil
}

@ -1,82 +1,82 @@
package implementations package implementations
import ( import (
"dymatrix.de/jspahl/todo/internal/models" "dymatrix.de/jspahl/todo/internal/models"
"dymatrix.de/jspahl/todo/internal/types" "dymatrix.de/jspahl/todo/internal/types"
) )
type SqlProvider struct { type SqlProvider struct {
} }
func (prov SqlProvider) CreateItem(item types.IItem) error { func (prov SqlProvider) CreateItem(item types.IItem) error {
storedItem := models.Item{Message: item.GetMessage()} storedItem := models.Item{Message: item.GetMessage()}
result := models.DB.Create(storedItem) result := models.DB.Create(storedItem)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
return nil return nil
} }
func (prov SqlProvider) UpdateItem(item types.IItem) error { func (prov SqlProvider) UpdateItem(item types.IItem) error {
var dbItem models.Item var dbItem models.Item
result := models.DB.First(&dbItem, item.GetId()) result := models.DB.First(&dbItem, item.GetId())
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
dbItem.Message = item.GetMessage() dbItem.Message = item.GetMessage()
result = models.DB.Save(&dbItem) result = models.DB.Save(&dbItem)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
return nil return nil
} }
func (prov SqlProvider) GetItem(id int) (types.IItem, error) { func (prov SqlProvider) GetItem(id int) (types.IItem, error) {
var dbItem models.Item var dbItem models.Item
result := models.DB.First(&dbItem, id) result := models.DB.First(&dbItem, id)
if result.Error != nil { if result.Error != nil {
return nil, result.Error return nil, result.Error
} }
return dbItem, nil return dbItem, nil
} }
func (prov SqlProvider) GetItemByUser(user types.IUser) ([]types.IItem, error) { func (prov SqlProvider) GetItemByUser(user types.IUser) ([]types.IItem, error) {
var dbUser models.User var dbUser models.User
if result := models.DB.Preload("Items").First(&dbUser, user.GetId()); result.Error != nil { if result := models.DB.Preload("Items").First(&dbUser, user.GetId()); result.Error != nil {
return nil, result.Error return nil, result.Error
} }
var items []types.IItem var items []types.IItem
for _, item := range dbUser.Items { for _, item := range dbUser.Items {
items = append(items, item) items = append(items, item)
} }
return items, nil return items, nil
} }
func (prov SqlProvider) GetAllItems() ([]types.IItem, error) { func (prov SqlProvider) GetAllItems() ([]types.IItem, error) {
var dbItems []models.Item var dbItems []models.Item
if err := models.DB.Find(&dbItems).Error; err != nil { if err := models.DB.Find(&dbItems).Error; err != nil {
return nil, err return nil, err
} }
var items []types.IItem var items []types.IItem
for _, item := range dbItems { for _, item := range dbItems {
items = append(items, item) items = append(items, item)
} }
return items, nil return items, nil
} }
func (prov SqlProvider) Link(user types.IUser, item types.IItem) error { func (prov SqlProvider) Link(user types.IUser, item types.IItem) error {
var dbUser models.User var dbUser models.User
if err := models.DB.First(&dbUser, user.GetId()).Error; err != nil { if err := models.DB.First(&dbUser, user.GetId()).Error; err != nil {
return err return err
} }
var dbItem models.Item var dbItem models.Item
if err := models.DB.First(&dbItem, item.GetId()).Error; err != nil { if err := models.DB.First(&dbItem, item.GetId()).Error; err != nil {
return err return err
} }
dbUser.Items = append(dbUser.Items, dbItem) dbUser.Items = append(dbUser.Items, dbItem)
dbItem.UserID = dbUser.ID dbItem.UserID = dbUser.ID
return models.DB.Save(&dbUser).Save(&dbItem).Error return models.DB.Save(&dbUser).Save(&dbItem).Error
} }
func (prov SqlProvider) DeleteItem(item types.IItem) error { func (prov SqlProvider) DeleteItem(item types.IItem) error {
return models.DB.Where("id = ?", item.GetId()).Delete(&models.Item{}).Error return models.DB.Where("id = ?", item.GetId()).Delete(&models.Item{}).Error
} }
func (prov SqlProvider) CreateUser(user types.IUser) (int, error) { func (prov SqlProvider) CreateUser(user types.IUser) (int, error) {
dbUser := models.User{} dbUser := models.User{}
err := models.DB.Create(&dbUser).Error err := models.DB.Create(&dbUser).Error
return int(dbUser.ID), err return int(dbUser.ID), err
} }

@ -1,17 +1,17 @@
package models package models
import "gorm.io/gorm" import "gorm.io/gorm"
type Item struct { type Item struct {
gorm.Model gorm.Model
Message string Message string
UserID uint UserID uint
} }
func (item Item) GetId() int { func (item Item) GetId() int {
return int(item.ID) return int(item.ID)
} }
func (item Item) GetMessage() string { func (item Item) GetMessage() string {
return item.Message return item.Message
} }

@ -1,17 +1,17 @@
package models package models
import "gorm.io/gorm" import "gorm.io/gorm"
type User struct { type User struct {
gorm.Model gorm.Model
UserName string UserName string
Items []Item Items []Item
} }
func (user User) GetId() int { func (user User) GetId() int {
return int(user.ID) return int(user.ID)
} }
func (user User) GetUsername() string { func (user User) GetUsername() string {
return user.UserName return user.UserName
} }

@ -1,20 +1,20 @@
package models package models
import ( import (
"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
) )
var DB *gorm.DB var DB *gorm.DB
func ConnectDatabase() error { func ConnectDatabase() error {
db, err := gorm.Open(sqlite.Open("dev.db"), &gorm.Config{}) db, err := gorm.Open(sqlite.Open("dev.db"), &gorm.Config{})
if err != nil { if err != nil {
return err return err
} }
db.AutoMigrate(&Item{}, &User{}) db.AutoMigrate(&Item{}, &User{})
DB = db DB = db
return nil return nil
} }

@ -1,24 +1,24 @@
package server package server
import ( import (
"dymatrix.de/jspahl/todo/internal/api" "dymatrix.de/jspahl/todo/internal/api"
"dymatrix.de/jspahl/todo/internal/implementations" "dymatrix.de/jspahl/todo/internal/implementations"
"dymatrix.de/jspahl/todo/internal/models" "dymatrix.de/jspahl/todo/internal/models"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func registerRoutes(router *gin.Engine) { func registerRoutes(router *gin.Engine) {
router.RedirectTrailingSlash = true router.RedirectTrailingSlash = true
memory := router.Group("/memory") memory := router.Group("/memory")
{ {
memoryProv := implementations.MemoryProvider{} memoryProv := implementations.MemoryProvider{}
api.RegisterRoutes(memory, memoryProv) api.RegisterRoutes(memory, memoryProv)
} }
sql := router.Group("/sql") sql := router.Group("/sql")
{ {
models.ConnectDatabase() models.ConnectDatabase()
sqlProvider := implementations.SqlProvider{} sqlProvider := implementations.SqlProvider{}
api.RegisterRoutes(sql, sqlProvider) api.RegisterRoutes(sql, sqlProvider)
} }
} }

@ -1,35 +1,35 @@
package server package server
import ( import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"dymatrix.de/jspahl/todo/internal/config" "dymatrix.de/jspahl/todo/internal/config"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var httpServer *http.Server var httpServer *http.Server
var httpRouter *gin.Engine var httpRouter *gin.Engine
func Setup() { func Setup() {
httpRouter = gin.New() httpRouter = gin.New()
httpRouter.Use(gin.Logger()) httpRouter.Use(gin.Logger())
registerRoutes(httpRouter) registerRoutes(httpRouter)
} }
func ListenAndServe() error { func ListenAndServe() error {
var err error = nil var err error = nil
for err == nil || err == http.ErrServerClosed { for err == nil || err == http.ErrServerClosed {
c := config.GetConfig() c := config.GetConfig()
httpServer = &http.Server{ httpServer = &http.Server{
Handler: httpRouter, Handler: httpRouter,
Addr: fmt.Sprintf("%s:%d", c.Listen.Host, c.Listen.Port), Addr: fmt.Sprintf("%s:%d", c.Listen.Host, c.Listen.Port),
} }
log.Printf("Starting web server at %s", httpServer.Addr) log.Printf("Starting web server at %s", httpServer.Addr)
err = httpServer.ListenAndServe() err = httpServer.ListenAndServe()
} }
return err return err
} }

@ -1,6 +1,6 @@
package types package types
type IItem interface { type IItem interface {
GetId() int GetId() int
GetMessage() string GetMessage() string
} }

@ -1,12 +1,12 @@
package types package types
type IPersitenceProvider interface { type IPersitenceProvider interface {
CreateItem(item IItem) error CreateItem(item IItem) error
UpdateItem(item IItem) error UpdateItem(item IItem) error
GetItem(id int) (IItem, error) GetItem(id int) (IItem, error)
GetItemByUser(user IUser) ([]IItem, error) GetItemByUser(user IUser) ([]IItem, error)
GetAllItems() ([]IItem, error) GetAllItems() ([]IItem, error)
Link(user IUser, item IItem) error Link(user IUser, item IItem) error
DeleteItem(item IItem) error DeleteItem(item IItem) error
CreateUser(user IUser) (int, error) CreateUser(user IUser) (int, error)
} }

@ -1,6 +1,6 @@
package types package types
type IUser interface { type IUser interface {
GetId() int GetId() int
GetUsername() string GetUsername() string
} }

@ -1,17 +1,17 @@
package main package main
import ( import (
"log" "log"
"dymatrix.de/jspahl/todo/internal/server" "dymatrix.de/jspahl/todo/internal/server"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func main() { func main() {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
server.Setup() server.Setup()
err := server.ListenAndServe() err := server.ListenAndServe()
log.Fatalf("http: webserver closed unexpected: %s", err) log.Fatalf("http: webserver closed unexpected: %s", err)
} }

Loading…
Cancel
Save