diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 3aaeec2..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/protoeditor.xml b/.idea/protoeditor.xml
deleted file mode 100644
index 2b7f969..0000000
--- a/.idea/protoeditor.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workout-training-api.iml b/.idea/workout-training-api.iml
deleted file mode 100644
index 5e764c4..0000000
--- a/.idea/workout-training-api.iml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docker-compose.askar.yml b/docker-compose.askar.yml
new file mode 100644
index 0000000..2546cec
--- /dev/null
+++ b/docker-compose.askar.yml
@@ -0,0 +1,17 @@
+version: '3.9'
+
+services:
+ postgres:
+ container_name: workout_postgres_container
+ image: postgres:17.3
+ ports:
+ - 5432:5432
+ environment:
+ POSTGRES_DB: "workoutdb"
+ POSTGRES_USER: "postgres"
+ POSTGRES_PASSWORD: "admin"
+ volumes:
+ - pgdata:/var/lib/postgresql/data
+
+volumes:
+ pgdata:
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 9c421ad..63f6b2e 100644
--- a/go.mod
+++ b/go.mod
@@ -36,4 +36,4 @@ require (
golang.org/x/tools v0.24.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
-)
\ No newline at end of file
+)
diff --git a/go.sum b/go.sum
index 0b8c4ba..bef4278 100644
--- a/go.sum
+++ b/go.sum
@@ -1,31 +1,3 @@
-<<<<<<< HEAD
-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/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
-github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
-github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
-github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
-github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
-github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
-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/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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
-golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
-golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
-golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-=======
github.com/99designs/gqlgen v0.17.64 h1:BzpqO5ofQXyy2XOa93Q6fP1BHLRjTOeU35ovTEsbYlw=
github.com/99designs/gqlgen v0.17.64/go.mod h1:kaxLetFxPGeBBwiuKk75NxuI1fe9HRvob17In74v/Zc=
github.com/PuerkitoBio/goquery v1.9.3 h1:mpJr/ikUA9/GNJB/DBZcGeFDXUtosHRyRrwh7KGdTG0=
@@ -114,6 +86,5 @@ google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNI
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
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=
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
\ No newline at end of file
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/askar-postgres/main.go b/internal/askar-postgres/main.go
new file mode 100644
index 0000000..731ad50
--- /dev/null
+++ b/internal/askar-postgres/main.go
@@ -0,0 +1,48 @@
+package askar_postgres
+
+import (
+ "context"
+ "database/sql"
+ _ "github.com/lib/pq"
+ "log/slog"
+ "time"
+ "workout-training-api/internal/askar-postgres/model"
+ "workout-training-api/internal/config"
+)
+
+type Postgres struct {
+ *model.Model
+}
+
+func New(conf *config.AskarPostgresConfig, logger *slog.Logger) (*Postgres, error) {
+ db, err := NewDatabase(conf)
+ if err != nil {
+ return nil, err
+ }
+ //defer db.Close()
+
+ return &Postgres{
+ Model: model.New(conf, logger.With(slog.String("module", "model")), db),
+ }, nil
+}
+
+func NewDatabase(conf *config.AskarPostgresConfig) (*sql.DB, error) {
+ //psqlInfo := fmt.Sprintf(
+ // "host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
+ // conf.Host, conf.Port, conf.User, conf.Password, conf.Name,
+ //)
+ db, err := sql.Open("postgres", conf.DSN)
+ if err != nil {
+ return nil, err
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+
+ err = db.PingContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ return db, nil
+}
diff --git a/internal/askar-postgres/migrations/000001_create_exercises_table.down.sql b/internal/askar-postgres/migrations/000001_create_exercises_table.down.sql
new file mode 100644
index 0000000..1b6d9a4
--- /dev/null
+++ b/internal/askar-postgres/migrations/000001_create_exercises_table.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS exercises;
\ No newline at end of file
diff --git a/internal/askar-postgres/migrations/000001_create_exercises_table.up.sql b/internal/askar-postgres/migrations/000001_create_exercises_table.up.sql
new file mode 100644
index 0000000..3bfb1c5
--- /dev/null
+++ b/internal/askar-postgres/migrations/000001_create_exercises_table.up.sql
@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS exercises (
+ id bigserial PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ repetitions INTEGER NOT NULL,
+ sets INTEGER NOT NULL,
+ weight INTEGER NOT NULL,
+ muscle_groups text [] NOT NULL,
+ categories text [] NOT NULL,
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
+);
\ No newline at end of file
diff --git a/internal/askar-postgres/migrations/000002_create_workouts_table.down.sql b/internal/askar-postgres/migrations/000002_create_workouts_table.down.sql
new file mode 100644
index 0000000..644b25f
--- /dev/null
+++ b/internal/askar-postgres/migrations/000002_create_workouts_table.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS workouts;
\ No newline at end of file
diff --git a/internal/askar-postgres/migrations/000002_create_workouts_table.up.sql b/internal/askar-postgres/migrations/000002_create_workouts_table.up.sql
new file mode 100644
index 0000000..78b4013
--- /dev/null
+++ b/internal/askar-postgres/migrations/000002_create_workouts_table.up.sql
@@ -0,0 +1,9 @@
+CREATE TABLE IF NOT EXISTS workouts (
+ id bigserial PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ status VARCHAR(255) NOT NULL,
+ scheduled_times TIMESTAMP WITH TIME ZONE[] NOT NULL,
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
+);
+
diff --git a/internal/askar-postgres/migrations/000003_exercise_workout_table.down.sql b/internal/askar-postgres/migrations/000003_exercise_workout_table.down.sql
new file mode 100644
index 0000000..5cd3187
--- /dev/null
+++ b/internal/askar-postgres/migrations/000003_exercise_workout_table.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS exercise_workout;
\ No newline at end of file
diff --git a/internal/askar-postgres/migrations/000003_exercise_workout_table.up.sql b/internal/askar-postgres/migrations/000003_exercise_workout_table.up.sql
new file mode 100644
index 0000000..52bf51c
--- /dev/null
+++ b/internal/askar-postgres/migrations/000003_exercise_workout_table.up.sql
@@ -0,0 +1,15 @@
+CREATE TABLE IF NOT EXISTS exercise_workout (
+ id bigserial PRIMARY KEY,
+ exercise_id BIGINT NOT NULL,
+ workout_id BIGINT NOT NULL,
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
+ CONSTRAINT fk_exercise
+ FOREIGN KEY (exercise_id)
+ REFERENCES exercises (id)
+ ON DELETE CASCADE,
+ CONSTRAINT fk_workout
+ FOREIGN KEY (workout_id)
+ REFERENCES workouts (id)
+ ON DELETE CASCADE
+);
diff --git a/internal/askar-postgres/migrations/000004_add_indexes_to_exercise_workout.down.sql b/internal/askar-postgres/migrations/000004_add_indexes_to_exercise_workout.down.sql
new file mode 100644
index 0000000..47800ca
--- /dev/null
+++ b/internal/askar-postgres/migrations/000004_add_indexes_to_exercise_workout.down.sql
@@ -0,0 +1,3 @@
+DROP INDEX IF EXISTS idx_exercise_workout_exercise_id;
+DROP INDEX IF EXISTS idx_exercise_workout_workout_id;
+
diff --git a/internal/askar-postgres/migrations/000004_add_indexes_to_exercise_workout.up.sql b/internal/askar-postgres/migrations/000004_add_indexes_to_exercise_workout.up.sql
new file mode 100644
index 0000000..b8bbee0
--- /dev/null
+++ b/internal/askar-postgres/migrations/000004_add_indexes_to_exercise_workout.up.sql
@@ -0,0 +1,2 @@
+CREATE INDEX IF NOT EXISTS idx_exercise_workout_exercise_id ON exercise_workout (exercise_id);
+CREATE INDEX IF NOT EXISTS idx_exercise_workout_workout_id ON exercise_workout (workout_id);
diff --git a/internal/askar-postgres/model/exercise/create_exercise.go b/internal/askar-postgres/model/exercise/create_exercise.go
new file mode 100644
index 0000000..969940c
--- /dev/null
+++ b/internal/askar-postgres/model/exercise/create_exercise.go
@@ -0,0 +1,54 @@
+package exercise
+
+import (
+ "context"
+ "fmt"
+ "github.com/lib/pq"
+ "time"
+ "workout-training-api/internal/types/database"
+)
+
+func (m *ExerciseModel) CreateExercise(ctx context.Context, req database.CreateExerciseReq) (database.CreateExerciseResp, error) {
+
+ log := m.logger.With("exercise", "CreateExercise")
+
+ if req == nil {
+ log.ErrorContext(ctx, "req is nil")
+ return nil, fmt.Errorf("req is nil")
+ }
+
+ mdl := &Exercise{
+ Name: req.GetName(),
+ Description: req.GetDescription(),
+ Repetitions: req.GetRepetitions(),
+ Sets: req.GetSets(),
+ Weight: req.GetWeight(),
+ MuscleGroups: req.GetMuscleGroups(),
+ Categories: req.GetCategories(),
+ }
+
+ query := `
+ INSERT INTO exercises (name, description, repetitions, sets, weight, muscle_groups, categories)
+ VALUES ($1, $2, $3, $4, $5, $6, $7)`
+
+ args := []interface{}{
+ mdl.Name,
+ mdl.Description,
+ mdl.Repetitions,
+ mdl.Sets,
+ mdl.Weight,
+ pq.Array(mdl.MuscleGroups),
+ pq.Array(mdl.Categories),
+ }
+
+ ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
+ defer cancel()
+
+ _, err := m.db.ExecContext(ctx, query, args...)
+ if err != nil {
+ log.ErrorContext(ctx, "failed to execute query", "error", err)
+ return nil, fmt.Errorf("failed to execute query: %w", err)
+ }
+
+ return true, nil
+}
diff --git a/internal/askar-postgres/model/exercise/delete_exercise.go b/internal/askar-postgres/model/exercise/delete_exercise.go
new file mode 100644
index 0000000..637b472
--- /dev/null
+++ b/internal/askar-postgres/model/exercise/delete_exercise.go
@@ -0,0 +1,43 @@
+package exercise
+
+import (
+ "context"
+ "fmt"
+ "time"
+ "workout-training-api/internal/types/database"
+)
+
+func (m *ExerciseModel) DeleteExercise(ctx context.Context, req database.DeleteExerciseReq) (database.DeleteExerciseResp, error) {
+ log := m.logger.With("exercise", "DeleteExercise")
+
+ if req == nil {
+ log.ErrorContext(ctx, "req is nil")
+ return nil, fmt.Errorf("req is nil")
+ }
+
+ query := `
+ DELETE FROM exercises
+ WHERE id = $1`
+
+ ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
+ defer cancel()
+
+ result, err := m.db.ExecContext(ctx, query, req.GetID())
+ if err != nil {
+ log.ErrorContext(ctx, "failed to delete exercise", "id", req.GetID())
+ return nil, fmt.Errorf("failed to delete exercise: %w", err)
+ }
+
+ rowsAffected, err := result.RowsAffected()
+ if err != nil {
+ log.ErrorContext(ctx, "failed to call rowsAffected", "id", req.GetID())
+ return nil, fmt.Errorf("failed to call rowsAffected: %w", err)
+ }
+
+ if rowsAffected == 0 {
+ log.ErrorContext(ctx, "failed to find an exercise with id", "id", req.GetID())
+ return nil, fmt.Errorf("failed to find an exercise")
+ }
+
+ return true, nil
+}
diff --git a/internal/askar-postgres/model/exercise/exercise.go b/internal/askar-postgres/model/exercise/exercise.go
new file mode 100644
index 0000000..4092966
--- /dev/null
+++ b/internal/askar-postgres/model/exercise/exercise.go
@@ -0,0 +1,57 @@
+package exercise
+
+import (
+ "strconv"
+ "time"
+)
+
+type Exercise struct {
+ ID int64
+ Name string
+ Description string
+ Repetitions int32
+ Sets int32
+ Weight int32
+ MuscleGroups []string
+ Categories []string
+ CreatedAt time.Time
+ UpdatedAt time.Time
+}
+
+func (e *Exercise) GetWorkoutID() string {
+ return "id"
+}
+
+func (e *Exercise) GetID() string {
+ return strconv.FormatInt(e.ID, 10)
+}
+
+func (e *Exercise) GetName() string {
+ return e.Name
+}
+
+func (e *Exercise) GetDescription() string {
+ return e.Description
+}
+
+func (e *Exercise) GetRepetitions() int32 { return e.Repetitions }
+
+func (e *Exercise) GetSets() int32 { return e.Sets }
+
+func (e *Exercise) GetWeight() int32 { return e.Weight }
+
+func (e *Exercise) GetMuscleGroups() []string {
+ return e.MuscleGroups
+}
+
+func (e *Exercise) GetCategories() []string {
+ return e.Categories
+}
+
+func (e *Exercise) GetCreatedAt() time.Time {
+ return e.CreatedAt
+}
+
+func (e *Exercise) GetUpdatedAt() time.Time {
+ return e.UpdatedAt
+}
diff --git a/internal/askar-postgres/model/exercise/list_exercise.go b/internal/askar-postgres/model/exercise/list_exercise.go
new file mode 100644
index 0000000..253f5ed
--- /dev/null
+++ b/internal/askar-postgres/model/exercise/list_exercise.go
@@ -0,0 +1,61 @@
+package exercise
+
+import (
+ "context"
+ "fmt"
+ "github.com/lib/pq"
+ "time"
+ "workout-training-api/internal/types/database"
+)
+
+type ExerciseList struct {
+ exercises []database.ExerciseResp
+}
+
+func (e ExerciseList) GetList() []database.ExerciseResp {
+ return e.exercises
+}
+
+func (m *ExerciseModel) ListExercise(ctx context.Context, _ database.ListExerciseReq) (database.ListExerciseResp, error) {
+ log := m.logger.With("exercise", "ListExercise")
+
+ query := `
+ SELECT id, name, description, repetitions, sets, weight, muscle_groups, categories, created_at, updated_at
+ FROM exercises`
+
+ ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
+ defer cancel()
+
+ rows, err := m.db.QueryContext(ctx, query)
+ if err != nil {
+ log.ErrorContext(ctx, "failed to query exercises")
+ return nil, fmt.Errorf("failed to query exercises: %w", err)
+ }
+
+ exercises := []database.ExerciseResp{}
+
+ for rows.Next() {
+ var exercise Exercise
+
+ err := rows.Scan(
+ &exercise.ID,
+ &exercise.Name,
+ &exercise.Description,
+ &exercise.Repetitions,
+ &exercise.Sets,
+ &exercise.Weight,
+ pq.Array(&exercise.MuscleGroups),
+ pq.Array(&exercise.Categories),
+ &exercise.CreatedAt,
+ &exercise.UpdatedAt,
+ )
+ if err != nil {
+ log.ErrorContext(ctx, "failed to scan exercise")
+ return nil, fmt.Errorf("failed to scan exercise: %w", err)
+ }
+
+ exercises = append(exercises, &exercise)
+ }
+
+ return ExerciseList{exercises: exercises}, nil
+}
diff --git a/internal/askar-postgres/model/exercise/main.go b/internal/askar-postgres/model/exercise/main.go
new file mode 100644
index 0000000..ceef21d
--- /dev/null
+++ b/internal/askar-postgres/model/exercise/main.go
@@ -0,0 +1,17 @@
+package exercise
+
+import (
+ "database/sql"
+ "log/slog"
+ "workout-training-api/internal/config"
+)
+
+type ExerciseModel struct {
+ conf *config.AskarPostgresConfig
+ logger *slog.Logger
+ db *sql.DB
+}
+
+func New(conf *config.AskarPostgresConfig, logger *slog.Logger, db *sql.DB) *ExerciseModel {
+ return &ExerciseModel{conf: conf, logger: logger, db: db}
+}
diff --git a/internal/askar-postgres/model/exercise/update_exercise.go b/internal/askar-postgres/model/exercise/update_exercise.go
new file mode 100644
index 0000000..66a864d
--- /dev/null
+++ b/internal/askar-postgres/model/exercise/update_exercise.go
@@ -0,0 +1,42 @@
+package exercise
+
+import (
+ "context"
+ "fmt"
+ "github.com/lib/pq"
+ "time"
+ "workout-training-api/internal/types/database"
+)
+
+func (m *ExerciseModel) UpdateExercise(ctx context.Context, req database.UpdateExerciseReq) (database.UpdateExerciseResp, error) {
+ log := m.logger.With("exercise", "UpdateExercise")
+
+ if req == nil {
+ log.ErrorContext(ctx, "req is nil")
+ return nil, fmt.Errorf("req is nil")
+ }
+
+ query := `
+ UPDATE exercises
+ SET name = $1, description = $2, categories = $3, muscle_groups = $4, updated_at = now()
+ WHERE id = $5`
+
+ args := []interface{}{
+ req.GetName(),
+ req.GetDescription(),
+ pq.Array(req.GetCategories()),
+ pq.Array(req.GetMuscleGroups()),
+ req.GetID(),
+ }
+
+ ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
+ defer cancel()
+
+ _, err := m.db.ExecContext(ctx, query, args...)
+ if err != nil {
+ log.ErrorContext(ctx, "failed to update exercise", "error", err)
+ return nil, fmt.Errorf("failed to update exercise: %w", err)
+ }
+
+ return true, nil
+}
diff --git a/internal/askar-postgres/model/main.go b/internal/askar-postgres/model/main.go
new file mode 100644
index 0000000..1998098
--- /dev/null
+++ b/internal/askar-postgres/model/main.go
@@ -0,0 +1,17 @@
+package model
+
+import (
+ "database/sql"
+ "log/slog"
+ "workout-training-api/internal/askar-postgres/model/exercise"
+ "workout-training-api/internal/config"
+)
+
+type Model struct {
+ *exercise.ExerciseModel
+}
+
+func New(conf *config.AskarPostgresConfig, logger *slog.Logger, db *sql.DB) *Model {
+
+ return &Model{ExerciseModel: exercise.New(conf, logger.With(slog.String("component", "exercise")), db)}
+}
diff --git a/internal/askar-postgres/model/seeds/main.go b/internal/askar-postgres/model/seeds/main.go
new file mode 100644
index 0000000..e504564
--- /dev/null
+++ b/internal/askar-postgres/model/seeds/main.go
@@ -0,0 +1,106 @@
+package seeds
+
+import (
+ "context"
+ "fmt"
+ "log/slog"
+ askar_postgres "workout-training-api/internal/askar-postgres"
+ "workout-training-api/internal/askar-postgres/model/exercise"
+)
+
+type Seed interface {
+ Populate() error
+ TestMethods() error
+}
+
+type seeder struct {
+ postgres *askar_postgres.Postgres
+}
+
+func New(postgres *askar_postgres.Postgres) Seed {
+ return &seeder{postgres: postgres}
+}
+
+func (s *seeder) Populate() error {
+
+ exercises := []*exercise.Exercise{
+ {
+ Name: "Push-ups",
+ Description: "A bodyweight exercise that targets the chest, shoulders, and triceps.",
+ Repetitions: 15,
+ Sets: 3,
+ Weight: 0,
+ MuscleGroups: []string{"Chest", "Triceps", "Shoulders"},
+ Categories: []string{"Bodyweight", "Strength"},
+ },
+ {
+ Name: "Squats",
+ Description: "A compound exercise that targets the legs and glutes.",
+ Repetitions: 12,
+ Sets: 3,
+ Weight: 50,
+ MuscleGroups: []string{"Quadriceps", "Hamstrings", "Glutes"},
+ Categories: []string{"Legs", "Strength"},
+ },
+ {
+ Name: "Deadlifts",
+ Description: "A strength exercise that targets the back, legs, and core.",
+ Repetitions: 8,
+ Sets: 4,
+ Weight: 100,
+ MuscleGroups: []string{"Back", "Hamstrings", "Core"},
+ Categories: []string{"Powerlifting", "Strength"},
+ },
+ }
+
+ for _, exercise := range exercises {
+ _, err := s.postgres.ExerciseModel.CreateExercise(context.Background(), exercise)
+ if err != nil {
+ slog.Error("Error on create exercise", err.Error())
+ }
+ }
+
+ return nil
+}
+
+func (s *seeder) TestMethods() error {
+ s.listExercise()
+ return nil
+}
+
+func (s *seeder) deleteExercise() {
+ req := &exercise.Exercise{
+ ID: 1,
+ }
+ _, err := s.postgres.DeleteExercise(context.Background(), req)
+ if err != nil {
+ slog.Error("Error on deleting exercise", err.Error())
+ }
+}
+
+func (s *seeder) listExercise() {
+ res, err := s.postgres.ExerciseModel.ListExercise(context.Background(), nil)
+ if err != nil {
+ slog.Error("Error on list exercise", err.Error())
+ }
+
+ for _, exercise := range res.GetList() {
+ fmt.Printf("exercise id %s and name %s\n", exercise.GetID(), exercise.GetName())
+ }
+}
+
+func (s *seeder) updateExercise() {
+ exercise := &exercise.Exercise{
+ ID: 2,
+ Name: "Updated Squats",
+ Description: "Updated A compound exercise that targets the legs and glutes.",
+ MuscleGroups: []string{"Updated Quadriceps", "Hamstrings", "Glutes"},
+ Categories: []string{"Updated Legs", "Strength"},
+ }
+
+ _, err := s.postgres.UpdateExercise(context.Background(), exercise)
+ if err != nil {
+ slog.Error("Error on update exercise", err.Error())
+ }
+ slog.Info("Exercise updated")
+}
diff --git a/internal/config/askar_postgres.go b/internal/config/askar_postgres.go
new file mode 100644
index 0000000..7beb2da
--- /dev/null
+++ b/internal/config/askar_postgres.go
@@ -0,0 +1,30 @@
+package config
+
+import (
+ "context"
+ "flag"
+)
+
+type AskarPostgresConfig struct {
+ DSN string
+}
+
+func newAskarPostgresConfig(_ context.Context) *AskarPostgresConfig {
+ var c AskarPostgresConfig
+
+ // postgres://workoutdb:admin@localhost/workoutdb?sslmode=disable
+ // postgres://postgres:admin@localhost/workoutdb
+ // postgres://postgres:admin@localhost/workoutdb?sslmode=disable
+
+ //flag.StringVar(&c.Host, "localhost", c.Host, "postgreSQL host [PG_HOST]")
+ //flag.IntVar(&c.Port, "pg-port", c.Port, "postgreSQL port [PG_PORT]")
+ //flag.StringVar(&c.Name, "pg-name", c.Name, "postgreSQL name [PG_NAME]")
+ //flag.StringVar(&c.User, "pg-user", c.User, "postgreSQL user [PG_USER]")
+ //flag.StringVar(&c.Password, "pg-password", c.Password, "postgreSQL password [PG_PASSWORD]")
+
+ flag.StringVar(&c.DSN, "askar-db-dsn", "postgres://postgres:admin@localhost/workoutdb?sslmode=disable", "Askar PostgreSQL DSN")
+
+ flag.Parse()
+
+ return &c
+}
diff --git a/internal/config/main.go b/internal/config/main.go
index 663598e..65b6523 100644
--- a/internal/config/main.go
+++ b/internal/config/main.go
@@ -3,16 +3,16 @@ package config
import (
"context"
"flag"
- "os"
-
"github.com/joho/godotenv"
+ "os"
"workout-training-api/internal/constant"
)
type Config struct {
- ENV constant.Environment
- API *APIConfig
- Postgres *PostgresConfig
+ ENV constant.Environment
+ API *APIConfig
+ Postgres *PostgresConfig
+ AskarPostgres *AskarPostgresConfig
}
func New(ctx context.Context) *Config {
@@ -27,9 +27,10 @@ func New(ctx context.Context) *Config {
load(env)
conf := &Config{
- ENV: env,
- API: newApiConfig(ctx),
- Postgres: newPostgresConfig(ctx),
+ ENV: env,
+ API: newApiConfig(ctx),
+ Postgres: newPostgresConfig(ctx),
+ AskarPostgres: newAskarPostgresConfig(ctx),
}
flag.Parse()
diff --git a/internal/config/postgres.go b/internal/config/postgres.go
index 6806709..c057dd9 100644
--- a/internal/config/postgres.go
+++ b/internal/config/postgres.go
@@ -18,19 +18,39 @@ type PostgresConfig struct {
func newPostgresConfig(_ context.Context) *PostgresConfig {
port, _ := strconv.Atoi(os.Getenv("PG_PORT"))
+ // c := &PostgresConfig{
+ // Host: os.Getenv("PG_HOST"),
+ // Port: port,
+ // Name: os.Getenv("PG_NAME"),
+ // User: os.Getenv("PG_USER"),
+ // Password: os.Getenv("PG_PASSWORD"),
+ // }
+
+ // flag.StringVar(&c.Host, "pg-host", c.Host, "postgreSQL host [PG_HOST]")
+ // flag.IntVar(&c.Port, "pg-port", c.Port, "postgreSQL port [PG_PORT]")
+ // flag.StringVar(&c.Name, "pg-name", c.Name, "postgreSQL name [PG_NAME]")
+ // flag.StringVar(&c.User, "pg-user", c.User, "postgreSQL user [PG_USER]")
+ // flag.StringVar(&c.Password, "pg-password", c.Password, "postgreSQL password [PG_PASSWORD]")
+
c := &PostgresConfig{
- Host: os.Getenv("PG_HOST"),
+ Host: "localhost",
Port: port,
- Name: os.Getenv("PG_NAME"),
- User: os.Getenv("PG_USER"),
- Password: os.Getenv("PG_PASSWORD"),
+ Name: "postgres",
+ User: "postgres",
+ Password: "postgres",
}
- flag.StringVar(&c.Host, "pg-host", c.Host, "postgreSQL host [PG_HOST]")
+ // postgres://workoutdb:admin@localhost/workoutdb?sslmode=disable
+ // postgres://postgres:admin@localhost/workoutdb
+ // postgres://postgres:admin@localhost/workoutdb?sslmode=disable
+
+ flag.StringVar(&c.Host, "localhost", c.Host, "postgreSQL host [PG_HOST]")
flag.IntVar(&c.Port, "pg-port", c.Port, "postgreSQL port [PG_PORT]")
flag.StringVar(&c.Name, "pg-name", c.Name, "postgreSQL name [PG_NAME]")
flag.StringVar(&c.User, "pg-user", c.User, "postgreSQL user [PG_USER]")
flag.StringVar(&c.Password, "pg-password", c.Password, "postgreSQL password [PG_PASSWORD]")
+ flag.Parse()
+
return c
}
diff --git a/internal/constant/env.go b/internal/constant/env.go
index e96307a..ad2aa11 100644
--- a/internal/constant/env.go
+++ b/internal/constant/env.go
@@ -1,6 +1,5 @@
package constant
-
type Environment string
const (
diff --git a/internal/types/database/create_exercise.go b/internal/types/database/create_exercise.go
index 1c505d5..b7b8ff8 100644
--- a/internal/types/database/create_exercise.go
+++ b/internal/types/database/create_exercise.go
@@ -1,54 +1,14 @@
package database
-import "context"
-
type CreateExerciseReq interface {
GetWorkoutID() string
GetName() string
- GetCategory() string
- GetMuscleGroup() string
- GetSets() int
- GetRepsPerSet() int
- GetWeightKg() float64
- GetNotes() string
+ GetDescription() string
+ GetRepetitions() int32
+ GetSets() int32
+ GetWeight() int32
+ GetMuscleGroups() []string
+ GetCategories() []string
}
type CreateExerciseResp interface{}
-
-func (d *Database) CreateExercise(ctx context.Context, req CreateExerciseReq) (CreateWorkoutResp, error) {
- _, err := d.DB.ExecContext(ctx, `
- INSERT INTO exercises (name, description, categories, muscle_groups)
- VALUES ($1, $2, $3, $4)`,
- req.GetName(), req.GetDescription(), req.GetCategories(), req.GetMuscleGroups(),
- )
- if err != nil {
- return nil, err
- }
-
- return struct{}{}, nil
-}
-
-type ExerciseModel struct {
- ID uint `gorm:"primaryKey"`
- WorkoutID uint `gorm:"index"`
- Name string
- Description string
- Categories []string `gorm:"type:text[]"`
- MuscleGroups []string `gorm:"type:text[]"`
- Reps int
- Sets int
-}
-
-func CreateExercise(ctx context.Context, wourkoutID uint, req CreateExerciseReq) (*ExerciseModel, error) {
- exercise := ExerciseModel{
- WorkoutID: wourkoutID,
- Name: req.GetName(),
- Description: req.GetDescription(),
- Categories: req.GetCategories(),
- MuscleGroups: req.GetMuscleGroups(),
- }
- if err := DB.WithContext(ctx).Create(&exercise).Error; err != nil {
- return nil, err
- }
- return &exercise, nil
-}
diff --git a/internal/types/database/create_user.go b/internal/types/database/create_user.go
index 8a6866c..58f0dc1 100644
--- a/internal/types/database/create_user.go
+++ b/internal/types/database/create_user.go
@@ -1,20 +1,9 @@
package database
-<<<<<<< HEAD
import (
- "context"
- "fmt"
+ "time"
)
-type User struct {
- ID uint `gorm:"primaryKey"`
- Email string `gorm:"unique"`
- PasswordHash string
-}
-=======
-import "time"
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
-
type CreateUserReq interface {
GetEmail() string
GetPasswordHash() string
@@ -27,19 +16,3 @@ type CreateUserResp interface {
GetCreatedAt() time.Time
GetUpdatedAt() time.Time
}
-
-type createUserResp struct {
- ID string
-}
-
-func (r createUserResp) GetID() string {
- return r.ID
-}
-
-func (d *Database) CreateUser(ctx context.Context, req CreateUserReq) (CreateUserResp, error) {
- user := User{Email: req.GetEmail(), PasswordHash: req.GetPasswordHash()}
- if err := d.DB.WithContext(ctx).Create(&user).Error; err != nil {
- return nil, err
- }
- return createUserResp{ID: fmt.Sprintf("%d", user.ID)}, nil
-}
diff --git a/internal/types/database/create_workout.go b/internal/types/database/create_workout.go
index cf86bd7..fb6261f 100644
--- a/internal/types/database/create_workout.go
+++ b/internal/types/database/create_workout.go
@@ -1,14 +1,9 @@
package database
import (
-<<<<<<< HEAD
- "context"
- "time"
-=======
"time"
"workout-training-api/internal/constant"
"workout-training-api/internal/postgres/db_types/workout"
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
)
type CreateWorkoutReq interface {
@@ -20,38 +15,6 @@ type CreateWorkoutReq interface {
GetScheduledDate() []time.Time
}
-<<<<<<< HEAD
-type CreateWorkoutResp interface{}
-
-func (d *Database) CreateWorkout(ctx context.Context, req CreateWorkoutReq) (CreateWorkoutResp, error) {
- _, err := d.DB.ExecContext(ctx, `
- INSERT INTO workouts (user_id, exercise_ids, scheduled_times)
- VALUES ($1, $2, $3)`,
- req.GetUserID(), req.GetExerciseIDs(), req.GetScheduledTimes(),
- )
- if err != nil {
- return nil, err
- }
-
- return struct{}{}, nil
-=======
type CreateWorkoutResp interface {
GetWorkout() workout.Workout
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
-}
-
-/*
-
-type Workout struct {
- WorkoutID string `db:"workout_id" json:"workout_id"`
- UserID string `db:"user_id" json:"user_id"`
- Name string `db:"name" json:"name"`
- Description string `db:"description" json:"description,omitempty"`
- Exercises []Exercise `json:"exercises,omitempty"` // Loaded separately
- Status constant.WorkoutStatus `db:"status" json:"status"`
- Comments []Comment `json:"comments,omitempty"` // Loaded separately
- ScheduledDate []*time.Time `db:"scheduled_date" json:"scheduled_date,omitempty"`
- CreatedAt *time.Time `db:"created_at" json:"created_at"`
- UpdatedAt *time.Time `db:"updated_at" json:"updated_at"`
}
-*/
diff --git a/internal/types/database/delete_exercise.go b/internal/types/database/delete_exercise.go
index ef3132a..dcc022b 100644
--- a/internal/types/database/delete_exercise.go
+++ b/internal/types/database/delete_exercise.go
@@ -1,24 +1,7 @@
package database
-import "context"
-
-// Интерфейс запроса на удаление упражнения
type DeleteExerciseReq interface {
GetID() string
}
-// Интерфейс ответа на удаление упражнения
type DeleteExerciseResp interface{}
-
-// Структура, реализующая DeleteExerciseResp (пустая, так как ответ не требуется)
-type deleteExerciseResp struct{}
-
-// Метод удаления упражнения в `Database`
-func (d *Database) DeleteExercise(ctx context.Context, req DeleteExerciseReq) (DeleteExerciseResp, error) {
- _, err := d.DB.ExecContext(ctx, `DELETE FROM exercises WHERE id = $1`, req.GetID())
- if err != nil {
- return nil, err
- }
-
- return deleteExerciseResp{}, nil
-}
diff --git a/internal/types/database/delete_workout.go b/internal/types/database/delete_workout.go
index 2ac602e..6bea991 100644
--- a/internal/types/database/delete_workout.go
+++ b/internal/types/database/delete_workout.go
@@ -1,19 +1,8 @@
package database
-import "context"
-
type DeleteWorkoutReq interface {
GetUserID() string
GetID() string
}
type DeleteWorkoutResp interface{}
-
-func (d *Database) DeleteWorkout(ctx context.Context, req DeleteWorkoutReq) (DeleteWorkoutResp, error) {
- _, err := d.DB.ExecContext(ctx, `DELETE FROM workouts WHERE id = $1 AND user_id = $2`, req.GetID(), req.GetUserID())
- if err != nil {
- return nil, err
- }
-
- return struct{}{}, nil
-}
diff --git a/internal/types/database/find_user.go b/internal/types/database/find_user.go
index b486cd2..4294a55 100644
--- a/internal/types/database/find_user.go
+++ b/internal/types/database/find_user.go
@@ -1,10 +1,8 @@
package database
-<<<<<<< HEAD
-import "context"
-=======
-import "time"
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
+import (
+ "time"
+)
type FindUserReq interface {
GetEmail() string
@@ -18,30 +16,3 @@ type FindUserResp interface {
GetCreatedAt() time.Time
GetUpdatedAt() time.Time
}
-
-type findUserResp struct {
- ID string
- Email string
-}
-
-func (r findUserResp) GetID() string {
- return r.ID
-}
-
-func (r findUserResp) GetEmail() string {
- return r.Email
-}
-
-func (d *Database) FindUser(ctx context.Context, req FindUserReq) (FindUserResp, error) {
- var id, email string
- err := d.DB.QueryRowContext(ctx, `
- SELECT id, email FROM users WHERE email = $1 AND password_hash = $2`,
- req.GetEmail(), req.GetPasswordHash(),
- ).Scan(&id, &email)
-
- if err != nil {
- return nil, err
- }
-
- return findUserResp{ID: id, Email: email}, nil
-}
diff --git a/internal/types/database/generate_workout_reports.go b/internal/types/database/generate_workout_reports.go
index 1fdba2d..ed8aca9 100644
--- a/internal/types/database/generate_workout_reports.go
+++ b/internal/types/database/generate_workout_reports.go
@@ -1,79 +1,10 @@
package database
-import (
- "context"
- "time"
-)
-
-// Интерфейс запроса отчета по тренировкам
type GenerateWorkoutReportsReq interface {
GetUserID() string
}
-// Интерфейс ответа отчета по тренировкам
type GenerateWorkoutReportsRes interface {
GetProgress() string
- GetWorkouts() []WorkoutResp
-}
-
-// Интерфейс для Workout
-type WorkoutResp interface {
- GetID() string
- GetUserID() string
- GetExerciseIDs() []string
- GetScheduledTimes() []time.Time
-}
-
-// Внутренняя структура данных для сканирования из базы
-type workoutData struct {
- ID string
- UserID string
- ExerciseIDs []string
- ScheduledTimes []time.Time
-}
-
-// Реализация методов для WorkoutResp
-func (w workoutData) GetID() string { return w.ID }
-func (w workoutData) GetUserID() string { return w.UserID }
-func (w workoutData) GetExerciseIDs() []string { return w.ExerciseIDs }
-func (w workoutData) GetScheduledTimes() []time.Time { return w.ScheduledTimes }
-
-// Реализация ответа для GenerateWorkoutReportsRes
-type generateWorkoutReportsRes struct {
- Progress string
- Workouts []WorkoutResp
-}
-
-func (r generateWorkoutReportsRes) GetProgress() string {
- return r.Progress
-}
-
-func (r generateWorkoutReportsRes) GetWorkouts() []WorkoutResp {
- return r.Workouts
-}
-
-// Метод GenerateWorkoutReports теперь работает через Database
-func (d *Database) GenerateWorkoutReports(ctx context.Context, req GenerateWorkoutReportsReq) (GenerateWorkoutReportsRes, error) {
- rows, err := d.DB.QueryContext(ctx, `
- SELECT id, user_id, exercise_ids, scheduled_times FROM workouts WHERE user_id = $1`, req.GetUserID())
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- var workouts []WorkoutResp
- for rows.Next() {
- var w workoutData
- err := rows.Scan(&w.ID, &w.UserID, &w.ExerciseIDs, &w.ScheduledTimes)
- if err != nil {
- return nil, err
- }
- workouts = append(workouts, w)
- }
-
- // Возвращаем структуру, реализующую интерфейс
- return generateWorkoutReportsRes{
- Progress: "In Progress", // Можно добавить реальную логику расчета прогресса
- Workouts: workouts,
- }, nil
+ GetWorkouts() WorkoutListResp
}
diff --git a/internal/types/database/list_exercise.go b/internal/types/database/list_exercise.go
index f437883..3bb7d58 100644
--- a/internal/types/database/list_exercise.go
+++ b/internal/types/database/list_exercise.go
@@ -1,19 +1,14 @@
package database
-import (
- "context"
- "time"
-)
+import "time"
-// Интерфейс запроса списка упражнений
-type ListExerciseReq interface{}
+type ListExerciseReq interface {
+}
-// Интерфейс ответа, содержащего список упражнений
type ListExerciseResp interface {
GetList() []ExerciseResp
}
-// Интерфейс одного упражнения
type ExerciseResp interface {
GetID() string
GetName() string
@@ -23,55 +18,3 @@ type ExerciseResp interface {
GetCreatedAt() time.Time
GetUpdatedAt() time.Time
}
-
-// Реализация `ExerciseResp`
-type exerciseData struct {
- ID string
- Name string
- Description string
- Categories []string
- MuscleGroups []string
- CreatedAt time.Time
- UpdatedAt time.Time
-}
-
-// Методы для реализации `ExerciseResp`
-func (e exerciseData) GetID() string { return e.ID }
-func (e exerciseData) GetName() string { return e.Name }
-func (e exerciseData) GetDescription() string { return e.Description }
-func (e exerciseData) GetCategories() []string { return e.Categories }
-func (e exerciseData) GetMuscleGroups() []string { return e.MuscleGroups }
-func (e exerciseData) GetCreatedAt() time.Time { return e.CreatedAt }
-func (e exerciseData) GetUpdatedAt() time.Time { return e.UpdatedAt }
-
-// Ответ `ListExerciseResp`, содержащий список упражнений
-type listExerciseResp struct {
- List []ExerciseResp
-}
-
-// Реализация метода `GetList()`
-func (r listExerciseResp) GetList() []ExerciseResp {
- return r.List
-}
-
-// Метод получения списка упражнений
-func (d *Database) ListExpense(ctx context.Context, req ListExerciseReq) (ListExerciseResp, error) {
- rows, err := d.DB.QueryContext(ctx, `
- SELECT id, name, description, categories, muscle_groups, created_at, updated_at FROM exercises`)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- var exercises []ExerciseResp
- for rows.Next() {
- var e exerciseData
- err := rows.Scan(&e.ID, &e.Name, &e.Description, &e.Categories, &e.MuscleGroups, &e.CreatedAt, &e.UpdatedAt)
- if err != nil {
- return nil, err
- }
- exercises = append(exercises, e)
- }
-
- return listExerciseResp{List: exercises}, nil
-}
diff --git a/internal/types/database/main.go b/internal/types/database/main.go
index 094ffd8..dc34eaf 100644
--- a/internal/types/database/main.go
+++ b/internal/types/database/main.go
@@ -2,16 +2,9 @@ package database
import (
"context"
-<<<<<<< HEAD
- "database/sql"
- "fmt"
-=======
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
)
-var DB *gorm.DB
-
-type UserService interface {
+type User interface {
CreateUser(context.Context, CreateUserReq) (CreateUserResp, error)
FindUserByEmail(context.Context, FindUserReq) (FindUserResp, error)
}
@@ -29,7 +22,7 @@ type Exercise interface {
CreateExercise(context.Context, CreateExerciseReq) (CreateExerciseResp, error)
UpdateExercise(context.Context, UpdateExerciseReq) (UpdateExerciseResp, error)
DeleteExercise(context.Context, DeleteExerciseReq) (DeleteExerciseResp, error)
- ListExpense(context.Context, ListExerciseReq) (ListWorkoutResp, error)
+ ListExercise(context.Context, ListExerciseReq) (ListExerciseResp, error)
}
type Workout interface {
@@ -40,29 +33,8 @@ type Workout interface {
GenerateWorkoutReports(context.Context, GenerateWorkoutReportsReq) (GenerateWorkoutReportsRes, error)
}
-<<<<<<< HEAD
-type Database struct {
- DB *sql.DB
-}
-
-func InitDB() (*Database, error) {
- connStr := "postgres://postgres:yourpassword@localhost:5432/postgres?sslmode=disable" // Замени пароль
-
- db, err := sql.Open("postgres", connStr)
- if err != nil {
- panic(fmt.Sprintf("Failed to connect to database: %v", err))
- }
-
- if err := db.Ping(); err != nil {
- panic(fmt.Sprintf("Database is not responding: %v", err))
- }
-
- fmt.Println("Connected to the database")
- return &Database{DB: db}, nil
-=======
type Database interface {
User
Exercise
Workout
->>>>>>> 12012e7eedb63c6cad288001c5cd429cb4ec7dde
}
diff --git a/internal/types/database/update_exercise.go b/internal/types/database/update_exercise.go
index ae7a1af..7ca31a7 100644
--- a/internal/types/database/update_exercise.go
+++ b/internal/types/database/update_exercise.go
@@ -1,13 +1,12 @@
package database
-import "time"
-
type UpdateExerciseReq interface {
+ GetID() string
GetName() string
GetDescription() string
GetCategories() []string
GetMuscleGroups() []string
- GetScheduledTimes() []time.Time
+ //GetScheduledTimes() []time.Time
}
type UpdateExerciseResp interface {
diff --git a/main.go b/main.go
index b549cb3..385dff5 100644
--- a/main.go
+++ b/main.go
@@ -2,66 +2,82 @@ package main
import (
"context"
- "fmt"
"log/slog"
- "os"
- "os/signal"
-
+ askar_postgres "workout-training-api/internal/askar-postgres"
+ "workout-training-api/internal/askar-postgres/model/seeds"
"workout-training-api/internal/config"
"workout-training-api/internal/constant"
- "workout-training-api/internal/controller"
- "workout-training-api/internal/graphql"
- "workout-training-api/internal/grpc"
- "workout-training-api/internal/postgres"
"workout-training-api/pkg/logger"
)
func main() {
- ctx, cancel := context.WithCancel(context.Background())
+ // ctx, cancel := context.WithCancel(context.Background())
- // config
- conf := config.New(ctx)
+ // // config
+ // conf := config.New(ctx)
- // logger
- log := logger.New(conf.ENV != constant.EnvironmentLocal)
+ // // logger
+ // log := logger.New(conf.ENV != constant.EnvironmentLocal)
- p, err := postgres.New(conf.Postgres, log.With(slog.String("service", "postgre")))
- if err != nil {
- log.ErrorContext(ctx, "failed to start postgre", slog.Any("error", err))
- panic(err)
- }
+ // p, err := postgres.New(conf.Postgres, log.With(slog.String("service", "postgre")))
+ // if err != nil {
+ // log.ErrorContext(ctx, "failed to start postgre", slog.Any("error", err))
+ // panic(err)
+ // }
+
+ // ctrl := controller.New(conf, p)
+
+ // gr := grpc.New(conf.API.Grpc, log.With(slog.String("service", "grpc")), ctrl)
+ // go func(ctx context.Context, cancelFunc context.CancelFunc) {
+ // if err := gr.Start(ctx); err != nil {
+ // log.ErrorContext(ctx, "failed to start grpc", slog.Any("error", err))
+ // }
+
+ // cancelFunc()
+ // }(ctx, cancel)
- ctrl := controller.New(conf, p)
+ // gql := graphql.New(conf.API.GraphQL, log.With(slog.String("service", "graphql")), ctrl)
+ // go func(ctx context.Context, cancelFunc context.CancelFunc) {
+ // if err := gql.Start(ctx); err != nil {
+ // log.ErrorContext(ctx, "failed to start graphql", slog.Any("error", err))
+ // }
- gr := grpc.New(conf.API.Grpc, log.With(slog.String("service", "grpc")), ctrl)
- go func(ctx context.Context, cancelFunc context.CancelFunc) {
- if err := gr.Start(ctx); err != nil {
- log.ErrorContext(ctx, "failed to start grpc", slog.Any("error", err))
- }
+ // cancelFunc()
+ // }(ctx, cancel)
- cancelFunc()
- }(ctx, cancel)
+ // go func(cancelFunc context.CancelFunc) {
+ // shutdown := make(chan os.Signal, 1) // Create channel to signify s signal being sent
+ // signal.Notify(shutdown, os.Interrupt) // When an interrupt is sent, notify the channel
- gql := graphql.New(conf.API.GraphQL, log.With(slog.String("service", "graphql")), ctrl)
- go func(ctx context.Context, cancelFunc context.CancelFunc) {
- if err := gql.Start(ctx); err != nil {
- log.ErrorContext(ctx, "failed to start graphql", slog.Any("error", err))
- }
+ // sig := <-shutdown
+ // log.WarnContext(ctx, "signal received - shutting down...", slog.Any("signal", sig))
- cancelFunc()
- }(ctx, cancel)
+ // cancelFunc()
+ // }(cancel)
- go func(cancelFunc context.CancelFunc) {
- shutdown := make(chan os.Signal, 1) // Create channel to signify s signal being sent
- signal.Notify(shutdown, os.Interrupt) // When an interrupt is sent, notify the channel
+ // <-ctx.Done()
- sig := <-shutdown
- log.WarnContext(ctx, "signal received - shutting down...", slog.Any("signal", sig))
+ // fmt.Println("shutting down gracefully")
- cancelFunc()
- }(cancel)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ // config
+ conf := config.New(ctx)
+
+ // logger
+ log := logger.New(conf.ENV != constant.EnvironmentLocal)
+
+ // postgres
+ p, err := askar_postgres.New(conf.AskarPostgres, log)
+ if err != nil {
+ log.ErrorContext(ctx, "failed to start postgres", slog.Any("error", err))
+ }
- <-ctx.Done()
+ seeder := seeds.New(p)
+ //seeder.Populate()
+ seeder.TestMethods()
+ //fmt.Print(db)
+ log.InfoContext(ctx, "postgres connection pool established", nil)
- fmt.Println("shutting down gracefully")
}