Added migrations
This commit is contained in:
parent
4a16acc87e
commit
5b18009658
34 changed files with 929 additions and 154 deletions
|
|
@ -7,18 +7,17 @@ import (
|
|||
"58team_blog/internal/application/queries"
|
||||
"58team_blog/internal/domain/entities"
|
||||
"58team_blog/internal/domain/repository"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PostService struct {
|
||||
repo repository.PostRepository
|
||||
postsService PostsService
|
||||
repo repository.PostRepository
|
||||
}
|
||||
|
||||
func CreatePostService(repo repository.PostRepository, postsService PostsService) PostService {
|
||||
func CreatePostService(repo repository.PostRepository) PostService {
|
||||
return PostService{
|
||||
repo: repo,
|
||||
postsService: postsService,
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +29,7 @@ func (s *PostService) Create(cmd commands.CreatePostCommand) (*common.PostResult
|
|||
|
||||
post, err := s.repo.Create(&entity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("Db error: %s", err)
|
||||
}
|
||||
|
||||
result := mapper.CreatePostResultFromEntity(post)
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ const PostTable = "post"
|
|||
|
||||
type Post struct {
|
||||
Id uuid.UUID `db:"id"`
|
||||
UserId uuid.UUID `db:"user_id"`
|
||||
UserId uuid.UUID `db:"userid"`
|
||||
Title string `db:"title"`
|
||||
Description string `db:"description"`
|
||||
Content string `db:"content"`
|
||||
CreatedAt time.Time `db:"createdAt"`
|
||||
UpdatedAt time.Time `db:"updatedAt"`
|
||||
CreatedAt time.Time `db:"createdat"`
|
||||
UpdatedAt time.Time `db:"updatedat"`
|
||||
}
|
||||
|
||||
func CreatePost(userId uuid.UUID, title string, description string, content string) (post Post, err error) {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ type Config struct {
|
|||
PostsPath string `mapstructure:"posts_path" default:"./posts/"`
|
||||
}
|
||||
|
||||
func LoadConfig() (config Config, err error) {
|
||||
config = Config{}
|
||||
func LoadConfig() (config *Config, err error) {
|
||||
config = &Config{}
|
||||
if err = defaults.Set(config); err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
viper.SetConfigName("config")
|
||||
|
|
@ -30,12 +30,12 @@ func LoadConfig() (config Config, err error) {
|
|||
viper.AddConfigPath("/58team_blog/cfgs/")
|
||||
|
||||
if err = viper.ReadInConfig(); err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = viper.Unmarshal(&config); err != nil {
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
return config, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
|
|
@ -13,7 +14,8 @@ type Database struct {
|
|||
|
||||
func DatabaseInit(config infrastructure.Config) (db *Database, err error) {
|
||||
db = &Database{}
|
||||
db_setup := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s", config.DBUser, config.DBPass, config.DBHost, config.DBPort, config.DBName)
|
||||
|
||||
db_setup := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=disable", config.DBUser, config.DBPass, config.DBHost, config.DBPort, config.DBName)
|
||||
db.Conn, err = sqlx.Connect("postgres", db_setup)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ func CreatePostRepository(conn *db.Database) PostRepository {
|
|||
}
|
||||
|
||||
func (r *PostRepository) Create(entity *entities.Post) (*entities.Post, error) {
|
||||
query := "INSERT INTO " + entities.PostTable + " (id, userId, title, description, content, createdAt, updatedAt)" +
|
||||
"VALUES (:id, :userId, :title, :description, :content, :createdAt, :updatedAt)"
|
||||
query := "INSERT INTO " + entities.PostTable + " (id, userid, title, description, content, createdat, updatedat)" +
|
||||
"VALUES (:id, :userid, :title, :description, :content, :createdat, :updatedat)"
|
||||
_, err := r.conn.Conn.NamedExec(query, entity)
|
||||
|
||||
return entity, err
|
||||
|
|
@ -43,7 +43,7 @@ func (r *PostRepository) FindById(id uuid.UUID) (*entities.Post, error) {
|
|||
|
||||
func (r *PostRepository) FindAllByUserName(userName string) ([]*entities.Post, error) {
|
||||
var entity_list []*entities.Post
|
||||
query := "SELECT * FROM " + entities.PostTable + " WHERE userId=?"
|
||||
query := "SELECT * FROM " + entities.PostTable + " WHERE userid=?"
|
||||
|
||||
query, args, err := sqlx.In(query, userName)
|
||||
if err != nil {
|
||||
|
|
@ -58,15 +58,15 @@ func (r *PostRepository) FindAllByUserName(userName string) ([]*entities.Post, e
|
|||
|
||||
func (r *PostRepository) GetAll() ([]*entities.Post, error) {
|
||||
var entity_list []*entities.Post
|
||||
query := "SELECT * FROM " + entities.PostTable
|
||||
query := "SELECT * FROM " + entities.PostTable + " ORDER BY createdat, updatedat LIMIT 5;"
|
||||
|
||||
err := r.conn.Conn.Select(entity_list, query)
|
||||
err := r.conn.Conn.Select(&entity_list, query)
|
||||
|
||||
return entity_list, err
|
||||
}
|
||||
|
||||
func (r *PostRepository) Update(entity *entities.Post) error {
|
||||
query := "UPDATE " + entities.PostTable + "SET title=:title, description=:description, content=:content, updatedAt=:updatedAt WHERE id=:id"
|
||||
query := "UPDATE " + entities.PostTable + "SET title=:title, description=:description, content=:content, updatedat=:updatedat WHERE id=:id"
|
||||
|
||||
_, err := r.conn.Conn.NamedExec(query, entity)
|
||||
|
||||
|
|
|
|||
43
internal/interfaces/api/controllers/images_controller.go
Normal file
43
internal/interfaces/api/controllers/images_controller.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ImagesController struct {
|
||||
service *services.ImagesService
|
||||
}
|
||||
|
||||
func CreateImagesController(service *services.ImagesService) ImagesController {
|
||||
return ImagesController{
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// get /images/{path}
|
||||
// post /images
|
||||
// delete /images/{id}
|
||||
|
||||
// @Summary Get an image by path
|
||||
// @Description get image by path
|
||||
// @Param path query string true "Path to image"
|
||||
// @Produce image/png
|
||||
// @Produce image/jpeg
|
||||
// @Success 200
|
||||
// @Router /images/{path} [get]
|
||||
func (r *ImagesController) GetImage(c *gin.Context) {
|
||||
// TODO: return image
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func (r *ImagesController) PostImage(c *gin.Context) {
|
||||
// TODO: return image
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func (r *ImagesController) DeleteImage(c *gin.Context) {
|
||||
// TODO: return image
|
||||
panic("Not implemented")
|
||||
}
|
||||
182
internal/interfaces/api/controllers/post_controller.go
Normal file
182
internal/interfaces/api/controllers/post_controller.go
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/commands"
|
||||
"58team_blog/internal/application/queries"
|
||||
"58team_blog/internal/application/services"
|
||||
"58team_blog/internal/interfaces/api/dto"
|
||||
"58team_blog/internal/interfaces/api/requests"
|
||||
"58team_blog/internal/interfaces/api/responses"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type PostController struct {
|
||||
service *services.PostService
|
||||
}
|
||||
|
||||
func CreatePostController(service *services.PostService) PostController {
|
||||
return PostController{
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// PostPost godoc
|
||||
//
|
||||
// @Summary Create new post
|
||||
// @Description Create new post in blog
|
||||
// @Tags post
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body requests.CreatePostRequest true "Post data"
|
||||
// @Success 200 {object} responses.PostResponse
|
||||
// @Failure 400 {object} responses.ErrorResponse
|
||||
// @Failure 500 {object} responses.ErrorResponse
|
||||
// @Router /post [post]
|
||||
func (r *PostController) Post(c *gin.Context) {
|
||||
var request requests.CreatePostRequest
|
||||
|
||||
if err := c.BindJSON(&request); err != nil {
|
||||
log.Println(err)
|
||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "BadRequest")
|
||||
c.IndentedJSON(resp.ErrorCode, resp)
|
||||
return
|
||||
}
|
||||
|
||||
userId, err := uuid.Parse(request.UserId)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Incorrect user id")
|
||||
c.IndentedJSON(resp.ErrorCode, resp)
|
||||
return
|
||||
}
|
||||
|
||||
cmd := commands.CreatePostCommand{
|
||||
UserId: userId,
|
||||
Title: request.Title,
|
||||
Description: request.Description,
|
||||
Content: request.Content,
|
||||
}
|
||||
|
||||
res, err := r.service.Create(cmd)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error")
|
||||
c.IndentedJSON(resp.ErrorCode, resp)
|
||||
return
|
||||
}
|
||||
|
||||
response := dto.ResponseFromPostResult(res)
|
||||
|
||||
c.IndentedJSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetAllPost godoc
|
||||
//
|
||||
// @Summary Get all posts
|
||||
// @Description Return first 5 posts
|
||||
// @Tags post
|
||||
// @Produce json
|
||||
// @Success 200 {array} responses.GetListPostResponseItem
|
||||
// @Failure 500 {object} responses.ErrorResponse
|
||||
// @Router /post [get]
|
||||
func (r *PostController) GetAll(c *gin.Context) {
|
||||
result, err := r.service.GetAll()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error")
|
||||
c.IndentedJSON(resp.ErrorCode, resp)
|
||||
return
|
||||
}
|
||||
|
||||
res := dto.ResponseFromPostGetAllResult(result)
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
}
|
||||
|
||||
// GetAllWithOffsetPost godoc
|
||||
// @Summary Get posts after offset
|
||||
// @Description return 5 posts after first offset posts
|
||||
// @Tags post
|
||||
// @Param offset query int true "Offset of posts"
|
||||
// @Produce json
|
||||
// @Success 200 {array} responses.GetListPostResponseItem
|
||||
// @Router /post/{offset} [get]
|
||||
func (r *PostController) GetAllWithOffset(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
// GetByIdPost godoc
|
||||
// @Summary Get post by id
|
||||
// @Description get post by id
|
||||
// @Tags post
|
||||
// @Param id query string true "Id of post"
|
||||
// @Produce json
|
||||
// @Success 200 {array} responses.PostResponse
|
||||
// @Failure 400 {object} responses.ErrorResponse
|
||||
// @Router /post/{id} [get]
|
||||
func (r *PostController) GetById(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
id_valid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
log.Println("User get by id error: ", err)
|
||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id")
|
||||
c.JSON(resp.ErrorCode, resp)
|
||||
return
|
||||
}
|
||||
|
||||
query := queries.PostFindByIdQuery{
|
||||
Id: id_valid,
|
||||
}
|
||||
|
||||
posts, err := r.service.FindById(query)
|
||||
if err != nil {
|
||||
log.Println("Post service error: ", err)
|
||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request")
|
||||
c.JSON(resp.ErrorCode, resp)
|
||||
return
|
||||
}
|
||||
|
||||
result := dto.ResponseFormPostFindByIdResult(posts)
|
||||
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// PutPost godoc
|
||||
// @Summary Update post content
|
||||
// @Description update post content
|
||||
// @Tags post
|
||||
// @Param id query string true "Id of post"
|
||||
//
|
||||
// @Param request body requests.PutPostRequest true "Post data"
|
||||
//
|
||||
// @Produce json
|
||||
// @Success 200 {object} responses.PostResponse
|
||||
// @Failure 400 {object} responses.ErrorResponse
|
||||
// @Router /post/{id} [put]
|
||||
func (r *PostController) Put(c *gin.Context) {
|
||||
var request requests.PutPostRequest
|
||||
|
||||
if err := c.BindJSON(request); err != nil {
|
||||
log.Println("Post request error: ", err)
|
||||
resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request")
|
||||
c.JSON(resp.ErrorCode, resp)
|
||||
}
|
||||
}
|
||||
|
||||
// Delete godoc
|
||||
// @Summary Delete post
|
||||
// @Description Delete post by id
|
||||
// @Tags post
|
||||
// @Param id query string true "Id of post"
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Router /post/{id} [delete]
|
||||
|
||||
func (r *PostController) Delete(c *gin.Context) {
|
||||
|
||||
}
|
||||
50
internal/interfaces/api/controllers/user_controller.go
Normal file
50
internal/interfaces/api/controllers/user_controller.go
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type UserController struct {
|
||||
service *services.UserService
|
||||
}
|
||||
|
||||
func CreateUserController(service *services.UserService) UserController {
|
||||
return UserController{
|
||||
service: service,
|
||||
}
|
||||
}
|
||||
|
||||
// @Summary Create new user
|
||||
// @Description Creates new user in system
|
||||
// @Param path query string true "Path to image"
|
||||
// @Produce
|
||||
// @Success 200
|
||||
// @Router /images/{path} [get]
|
||||
func (r *UserController) Post(c *gin.Context) {
|
||||
// TODO: return image
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func (r *UserController) FindById(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (r *UserController) FindByName(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (r *UserController) GetAll(c *gin.Context) {
|
||||
// TODO: return image
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
func (r *UserController) Put(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (r *UserController) Delete(c *gin.Context) {
|
||||
// TODO: return image
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package dto
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/queries"
|
||||
"58team_blog/internal/interfaces/api/responses"
|
||||
)
|
||||
|
||||
func ResponseFormPostFindByIdResult(result *queries.PostFindByIdResult) responses.PostResponse {
|
||||
res := result.Result
|
||||
return responses.PostResponse{
|
||||
Id: res.Id.String(),
|
||||
UserId: res.UserId.String(),
|
||||
Title: res.Title,
|
||||
Description: res.Description,
|
||||
Content: res.Content,
|
||||
CreatedAt: res.CreatedAt,
|
||||
UpdatedAt: res.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package dto
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/common"
|
||||
"58team_blog/internal/application/queries"
|
||||
"58team_blog/internal/interfaces/api/responses"
|
||||
)
|
||||
|
||||
func itemFromResult(item *common.PostResult) responses.GetListPostResponseItem {
|
||||
return responses.GetListPostResponseItem{
|
||||
Id: item.Id.String(),
|
||||
Title: item.Title,
|
||||
Description: item.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func ResponseFromPostGetAllResult(result *queries.PostGetAllResult) responses.GetListPostResponse {
|
||||
var resp []responses.GetListPostResponseItem
|
||||
|
||||
for _, r := range result.Result.Result {
|
||||
resp = append(resp, itemFromResult(r))
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
18
internal/interfaces/api/dto/response_from_post_result.go
Normal file
18
internal/interfaces/api/dto/response_from_post_result.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package dto
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/common"
|
||||
"58team_blog/internal/interfaces/api/responses"
|
||||
)
|
||||
|
||||
func ResponseFromPostResult(result *common.PostResult) responses.PostResponse {
|
||||
return responses.PostResponse{
|
||||
Id: result.Id.String(),
|
||||
UserId: result.UserId.String(),
|
||||
Title: result.Title,
|
||||
Description: result.Description,
|
||||
Content: result.Content,
|
||||
CreatedAt: result.CreatedAt,
|
||||
UpdatedAt: result.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
package api
|
||||
|
|
@ -1 +0,0 @@
|
|||
package api
|
||||
8
internal/interfaces/api/requests/create_post_request.go
Normal file
8
internal/interfaces/api/requests/create_post_request.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package requests
|
||||
|
||||
type CreatePostRequest struct {
|
||||
Title string `json:"title" validate:"required,min=8,max=255"`
|
||||
Description string `json:"description" validate:"required,min=8,max=255"`
|
||||
Content string `json:"content" validate:"required,min=36"`
|
||||
UserId string `json:"userId" validate:"required,uuid5"`
|
||||
}
|
||||
7
internal/interfaces/api/requests/put_post_response.go
Normal file
7
internal/interfaces/api/requests/put_post_response.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package requests
|
||||
|
||||
type PutPostRequest struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
13
internal/interfaces/api/responses/error_response.go
Normal file
13
internal/interfaces/api/responses/error_response.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package responses
|
||||
|
||||
type ErrorResponse struct {
|
||||
ErrorCode int `json:"error_code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func CreateErrorResponse(code int, msg string) ErrorResponse {
|
||||
return ErrorResponse{
|
||||
ErrorCode: code,
|
||||
Message: msg,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package responses
|
||||
|
||||
type GetListPostResponseItem struct {
|
||||
Id string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type GetListPostResponse []GetListPostResponseItem
|
||||
15
internal/interfaces/api/responses/post_response.go
Normal file
15
internal/interfaces/api/responses/post_response.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package responses
|
||||
|
||||
import "time"
|
||||
|
||||
type PostResponse struct {
|
||||
Id string `json:"id"`
|
||||
UserId string `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Content string `json:"content"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type PostResponseList []*PostResponse
|
||||
|
|
@ -1 +0,0 @@
|
|||
package api
|
||||
|
|
@ -1 +1,18 @@
|
|||
package interfaces
|
||||
|
||||
import (
|
||||
"58team_blog/internal/application/services"
|
||||
"58team_blog/internal/interfaces/api/controllers"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func BindPostAdmin(service *services.PostService, group *gin.RouterGroup) {
|
||||
post := controllers.CreatePostController(service)
|
||||
|
||||
g := group.Group("/post")
|
||||
g.GET("/", post.GetAllPost)
|
||||
g.GET("/:id", post.GetByIdPost)
|
||||
g.POST("/", post.PostPost)
|
||||
g.PUT("/:id", post.PutPost)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue