This commit is contained in:
yash 2024-01-19 15:49:26 +03:00
parent f4bf66ea1b
commit 632d69ccda
4 changed files with 177 additions and 11 deletions

View File

@ -0,0 +1,21 @@
package models
type Recipe struct {
ID uint `json:"id,omitempty"` // id
Title string `json:"title,omitempty"` // Заголовок
Description string `json:"desc,omitempty"` // Описание
Image string `json:"img,omitempty"` // Картинка
CookingTime string `json:"ctime,omitempty"` // Время приготовления
Link string `json:"link,omitempty"` // Ссылка
ServingsNum uint `json:"snum,omitempty"` // Кол-во порций
Calories string `json:"cal,omitempty"` // Колории
Ingredients []RecipeIngredients `json:"ingredients,omitempty"` // Ингридиенты и посуда (списки)
Recipe_steps []string `json:"recipe_steps,omitempty"` // Шаги рецепта
Advices []string `json:"advices,omitempty"` // Рекомендации
Categories []string `json:"categories,omitempty"` // Категории
}
type RecipeIngredients struct {
Title string `json:"title,omitempty"`
Ingredients []string `json:"ingredients,omitempty"`
}

View File

@ -3,15 +3,16 @@ package postgresql
import ( import (
"context" "context"
"fmt" "fmt"
"recipes/internal/domain/models"
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
) )
type Database struct { type Storage struct {
db *pgxpool.Pool db *pgxpool.Pool
} }
func New(user, password, addr, dbname string) (*Database, error) { func New(user, password, addr, dbname string) (*Storage, error) {
const op = "storage.postgresql.New" const op = "storage.postgresql.New"
pool, err := pgxpool.New(context.Background(), fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=disable", user, password, addr, dbname)) pool, err := pgxpool.New(context.Background(), fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=disable", user, password, addr, dbname))
@ -19,5 +20,149 @@ func New(user, password, addr, dbname string) (*Database, error) {
return nil, fmt.Errorf("%s: %w", op, err) return nil, fmt.Errorf("%s: %w", op, err)
} }
return &Database{db: pool}, nil return &Storage{db: pool}, nil
} }
// AddRecipe adds recipe to db.
func (s *Storage) AddRecipe(ctx context.Context, recipe models.Recipe) error {
const op = "storage.postgresql.AddRecipe"
// open transaction
tx, err := s.db.Begin(ctx)
if err != nil {
return fmt.Errorf("%s: %w", op, err)
}
// refactor error handling
// rollback transaction on return
defer tx.Rollback(ctx)
var id uint
// insert recipe
err = s.db.QueryRow(
ctx,
"insert into recipe (title, description, image, cooking_time, servings, cal) values ($1, $2, $3, $4, $5, $6) returning id",
recipe.Title, recipe.Description, recipe.Image, recipe.CookingTime, recipe.ServingsNum, recipe.Calories,
).Scan(&id)
// insert ingredients
for _, r := range recipe.Ingredients {
var ing_id uint
err = s.db.QueryRow(
ctx,
"insert into recipe_ingredients_group (recipe_id, title) values ($1, $2) returning id",
id, r.Title,
).Scan(&ing_id)
if err != nil {
return fmt.Errorf("%s: %w", op, err)
}
for _, i := range r.Ingredients {
_, err = s.db.Exec(
ctx,
"insert into recipe_ingredients (recipe_ingredients_group_id, ingredient) values ($1, $2)",
ing_id, i,
)
if err != nil {
return fmt.Errorf("%s: %w", op, err)
}
}
}
// insert steps
for i, step := range recipe.Recipe_steps {
s.db.Exec(
ctx,
"insert into recipe_steps (recipe_id, step_num, step_text) values ($1, $2, $3)",
id, i, step,
)
}
// insert advices
for _, a := range recipe.Advices {
s.db.Exec(
ctx,
"insert into recipe_advices (recipe_id, advice) values ($1, $2)",
id, a,
)
}
// insert categories
for _, c := range recipe.Categories {
s.db.Exec(
ctx,
"insert into recipe_categories (recipe_id, category) values ($1, $2)",
id, c,
)
}
// commit transaction
if err := tx.Commit(ctx); err != nil {
return fmt.Errorf("%s: %w", op, err)
}
return nil
}
// RecipeExists returns true if recipe is exists.
func (s *Storage) RecipeExists(ctx context.Context, title string) (bool, error) {
const op = "storage.postgresql.RecipeExists"
var exists bool
err := s.db.QueryRow(
ctx,
"select exists(select id from recipe where title = $1)",
title,
).Scan(&exists)
if err != nil {
return false, fmt.Errorf("%s: %w", op, err)
}
return exists, nil
}
// func (db *PostgresqlDatabase) GetRecipes(offset, limit int) ([]structs.Recipe, error)
func (s *Storage) GetRecipes(ctx context.Context, offset, limit int) ([]models.Recipe, error) {
const op = "storage.postgresql.GetRecipes"
rows, err := s.db.Query(
ctx,
"select id, title, image, cooking_time, cal from recipe order by id desc offset $1 limit $2",
offset, limit,
)
if err != nil {
return nil, fmt.Errorf("%s: %w", op, err)
}
defer rows.Close()
var recipes []models.Recipe = make([]models.Recipe, 0, limit)
for rows.Next() {
var r models.Recipe
err = rows.Scan(
&r.ID,
&r.Title,
&r.Image,
&r.CookingTime,
&r.Calories,
)
if err != nil {
return nil, fmt.Errorf("%s: %w", op, err)
}
recipes = append(recipes, r)
}
return recipes, nil
}
// func (db *PostgresqlDatabase) GetRecipe(r_id uint) (structs.Recipe, error)
// add to recipe info about ingredients, steps, advices, categories
// func (db *PostgresqlDatabase) AddRecipeInformation(r *structs.Recipe)
// get recipes by category
// func (db *PostgresqlDatabase) GetRecipesByCategory(offset, limit int, category string) ([]structs.Recipe, error)

View File

@ -1,6 +1,6 @@
drop table if exists recipe; drop table if exists recipe_ingredients_group cascade;
drop table if exists recipe_ingredients_group; drop table if exists recipe_ingredients cascade;
drop table if exists recipe_ingredients; drop table if exists recipe_steps cascade;
drop table if exists recipe_steps; drop table if exists recipe_advices cascade;
drop table if exists recipe_advices; drop table if exists recipe_categories cascade;
drop table if exists recipe_categories; drop table if exists recipe cascade;

View File

@ -1,7 +1,7 @@
-- recipe -- recipe
create table if not exists recipe ( create table if not exists recipe (
id serial primary key, id serial primary key,
title varchar(60) not null UNIQUE, title text not null UNIQUE,
description text not null default '', description text not null default '',
image varchar(42) not null, image varchar(42) not null,
cooking_time varchar(16) not null, cooking_time varchar(16) not null,
@ -12,7 +12,7 @@ create table if not exists recipe (
create table if not exists recipe_ingredients_group ( create table if not exists recipe_ingredients_group (
id serial primary key, id serial primary key,
recipe_id integer references recipe(id) on delete cascade, recipe_id integer references recipe(id) on delete cascade,
title varchar(26) default '' title text default ''
); );
-- recipe ingredients -- recipe ingredients
create table if not exists recipe_ingredients ( create table if not exists recipe_ingredients (