Skip to content

Commit

Permalink
ref
Browse files Browse the repository at this point in the history
  • Loading branch information
Olegsuus committed Jun 18, 2024
1 parent b37f7a8 commit de51d28
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 64 deletions.
7 changes: 4 additions & 3 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (

func main() {
cfg := config.GetConfig()
db := &database.DataBase{}
db.GetStorage(cfg)
migrations.Migrations(cfg, db.DB.DB)
db := database.NewDB(cfg)
defer db.Close()

migrations.MigrateUp(db.DB)

app := &app.App{
Config: cfg,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ require (
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/mfridman/interpolate v0.0.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
Expand Down
4 changes: 1 addition & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand All @@ -65,8 +63,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
Expand Down
19 changes: 8 additions & 11 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,35 @@ package app
import (
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/logger"
"log"
"news-api/internal/config"
"news-api/internal/models"
"news-api/internal/database"
)

type App struct {
Config *config.Config
DB Storage
DB *database.DB
ServerInterface ServerInterface
Echo *fiber.App
}

type Storage interface {
Stop() error
GetAllNews() ([]models.News, error)
GetNewsByID(int64) (*models.News, error)
CreateNews(*models.News) error
UpdateNews(*models.News) error
DeleteNews(int64) error
type ServerInterface interface {
GetServer(*App)
}

func (a *App) Start() error {
a.Echo.Use(logger.New())

a.ServerInterface.GetServer(a)

addr := fmt.Sprintf(":%d", a.Config.Server.Port)
log.Printf("Starting server on %s", addr)
return a.Echo.Listen(addr)
}

// Stop закрывает соединение с базой данных, если есть ошибки
func (a *App) Stop() {
if err := a.DB.Stop(); err != nil {
if err := a.DB.Close(); err != nil {
log.Fatalf("Failed to close database: %v", err)
}
}
27 changes: 17 additions & 10 deletions internal/app/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,26 @@ import (
"strconv"
)

// HandleGetAllNews обработчик для получения всех новостей
func (a *App) HandleGetAllNews(c *fiber.Ctx) error {
newsList, err := a.DB.GetAllNews()
page, err := strconv.Atoi(c.Query("page", "1"))
if err != nil || page < 1 {
page = 1
}

limit, err := strconv.Atoi(c.Query("limit", "10"))
if err != nil || limit < 1 {
limit = 10
}

offset := (page - 1) * limit

newsList, err := a.DB.GetAllNews(limit, offset)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to fetch news"})
}
return c.JSON(fiber.Map{"success": true, "news": newsList})
return c.Status(fiber.StatusOK).JSON(fiber.Map{"success": true, "news": newsList})
}

// HandleGetNewsByID обработчик для получения новости по id
func (a *App) HandleGetNewsByID(c *fiber.Ctx) error {
id, err := strconv.ParseInt(c.Params("id"), 10, 64)
if err != nil {
Expand All @@ -25,10 +35,9 @@ func (a *App) HandleGetNewsByID(c *fiber.Ctx) error {
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "news not found"})
}
return c.JSON(news)
return c.Status(fiber.StatusOK).JSON(news)
}

// HandleCreateNews обработчик для создания новостей
func (a *App) HandleCreateNews(c *fiber.Ctx) error {
var news models.News
if err := c.BodyParser(&news); err != nil {
Expand All @@ -40,7 +49,6 @@ func (a *App) HandleCreateNews(c *fiber.Ctx) error {
return c.Status(fiber.StatusCreated).JSON(news)
}

// HandleUpdateNews обработчик для обновления новостей
func (a *App) HandleUpdateNews(c *fiber.Ctx) error {
id, err := strconv.ParseInt(c.Params("id"), 10, 64)
if err != nil {
Expand All @@ -54,10 +62,9 @@ func (a *App) HandleUpdateNews(c *fiber.Ctx) error {
if err := a.DB.UpdateNews(&news); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to update news"})
}
return c.JSON(news)
return c.Status(fiber.StatusOK).JSON(news)
}

// HandleDeleteNews обработчик для удаления новостей
func (a *App) HandleDeleteNews(c *fiber.Ctx) error {
id, err := strconv.ParseInt(c.Params("id"), 10, 64)
if err != nil {
Expand All @@ -66,5 +73,5 @@ func (a *App) HandleDeleteNews(c *fiber.Ctx) error {
if err := a.DB.DeleteNews(id); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to delete news"})
}
return c.JSON(fiber.Map{"message": "news deleted"})
return c.Status(fiber.StatusOK).JSON(fiber.Map{"message": "news deleted"})
}
4 changes: 0 additions & 4 deletions internal/app/server.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package app

type ServerInterface interface {
GetServer(*App)
}

type Server struct{}

func (s *Server) GetServer(app *App) {
Expand Down
47 changes: 24 additions & 23 deletions internal/database/storage.go
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
package database

import (
"database/sql"
"fmt"
"log"
"news-api/internal/config"
"news-api/internal/models"

"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"gopkg.in/reform.v1"
"gopkg.in/reform.v1/dialects/postgresql"
)

type DataBase struct {
DB *sqlx.DB
type DB struct {
DB *reform.DB
}

func (db *DataBase) GetStorage(cfg *config.Config) {
func NewDB(cfg *config.Config) *DB {
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
cfg.Database.Host, cfg.Database.Port, cfg.Database.User, cfg.Database.Password, cfg.Database.DBName)

sqlDB, err := sqlx.Open("postgres", dsn)
sqlDB, err := sql.Open("postgres", dsn)
if err != nil {
log.Fatalf("Failed to open database: %v", err)
}

db.DB = sqlDB
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
return &DB{DB: db}
}

func (db *DataBase) Stop() error {
return db.DB.Close()
func (db *DB) Close() error {
return db.DB.DBInterface().(*sql.DB).Close()
}

func (db *DataBase) GetAllNews() ([]models.News, error) {
func (db *DB) GetAllNews(limit, offset int) ([]models.News, error) {
var newsList []models.News
err := db.DB.Select(&newsList, "SELECT * FROM news")
err := db.DB.SelectAllFrom(models.NewsTable, "LIMIT ? OFFSET ?", limit, offset, &newsList)
return newsList, err
}

func (db *DataBase) GetNewsByID(id int64) (*models.News, error) {
var news models.News
err := db.DB.Get(&news, "SELECT * FROM news WHERE id=$1", id)
return &news, err
func (db *DB) GetNewsByID(id int64) (*models.News, error) {
news := &models.News{}
err := db.DB.FindByPrimaryKeyTo(news, id)
return news, err
}

func (db *DataBase) CreateNews(news *models.News) error {
_, err := db.DB.NamedExec("INSERT INTO news (title, content) VALUES (:title, :content)", news)
return err
func (db *DB) CreateNews(news *models.News) error {
return db.DB.Save(news)
}

func (db *DataBase) UpdateNews(news *models.News) error {
_, err := db.DB.NamedExec("UPDATE news SET title=:title, content=:content WHERE id=:id", news)
return err
func (db *DB) UpdateNews(news *models.News) error {
return db.DB.Update(news)
}

func (db *DataBase) DeleteNews(id int64) error {
_, err := db.DB.Exec("DELETE FROM news WHERE id=$1", id)
return err
func (db *DB) DeleteNews(id int64) error {
news := &models.News{ID: id}
return db.DB.Delete(news)
}
8 changes: 3 additions & 5 deletions internal/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@ import (
"embed"
"github.com/pressly/goose/v3"
"log"
"news-api/internal/config"
)

//go:embed migrations/*.sql
//go:embed *.sql
var embedMigrations embed.FS

func Migrations(cfg *config.Config, db *sql.DB) {

func MigrateUp(db *sql.DB) {
goose.SetBaseFS(embedMigrations)

if err := goose.SetDialect("postgres"); err != nil {
log.Fatalf("Failed to set goose dialect: %v", err)
}

if err := goose.Up(db, "migrations"); err != nil {
if err := goose.Up(db, "."); err != nil {
log.Fatalf("Failed to apply migrations: %v", err)
}

Expand Down
22 changes: 18 additions & 4 deletions internal/models/models.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package models

// News представляет структуру новости.
import (
"time"
)

type News struct {
ID int64 `db:"id" json:"id"`
Title string `db:"title" json:"title"`
Content string `db:"content" json:"content"`
ID int64 `reform:"id,pk" json:"id"`
Title string `reform:"title" json:"title"`
Content string `reform:"content" json:"content"`
CreatedAt time.Time `reform:"created_at" json:"created_at"`
UpdatedAt time.Time `reform:"updated_at" json:"updated_at"`
}

// NewsTable is the reform table identifier for News.
const NewsTable = "news"

// NewsCategory represents the relationship between news and categories.
type NewsCategory struct {
NewsID int64 `reform:"news_id,pk" json:"news_id"`
CategoryID int64 `reform:"category_id,pk" json:"category_id"`
}

0 comments on commit de51d28

Please sign in to comment.