package repository import ( "context" "git.techease.ru/Smart-search/smart-search-back/internal/model" errs "git.techease.ru/Smart-search/smart-search-back/pkg/errors" sq "github.com/Masterminds/squirrel" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) type supplierRepository struct { pool *pgxpool.Pool qb sq.StatementBuilderType } func NewSupplierRepository(pool *pgxpool.Pool) SupplierRepository { return &supplierRepository{ pool: pool, qb: sq.StatementBuilder.PlaceholderFormat(sq.Dollar), } } func (r *supplierRepository) BulkInsert(ctx context.Context, requestID uuid.UUID, suppliers []*model.Supplier) error { return r.bulkInsertWithExecutor(ctx, r.pool, requestID, suppliers) } func (r *supplierRepository) BulkInsertTx(ctx context.Context, tx pgx.Tx, requestID uuid.UUID, suppliers []*model.Supplier) error { return r.bulkInsertWithExecutor(ctx, tx, requestID, suppliers) } func (r *supplierRepository) bulkInsertWithExecutor(ctx context.Context, exec DBTX, requestID uuid.UUID, suppliers []*model.Supplier) error { if len(suppliers) == 0 { return nil } query := r.qb.Insert("suppliers").Columns( "request_id", "name", "email", "phone", "adress", "url", ) for _, s := range suppliers { query = query.Values(requestID, s.Name, s.Email, s.Phone, s.Address, s.URL) } query = query.Suffix("RETURNING id") sqlQuery, args, err := query.ToSql() if err != nil { return errs.NewInternalError(errs.DatabaseError, "failed to build query", err) } rows, err := exec.Query(ctx, sqlQuery, args...) if err != nil { return errs.NewInternalError(errs.DatabaseError, "failed to bulk insert suppliers", err) } defer rows.Close() i := 0 for rows.Next() { if i >= len(suppliers) { break } if err := rows.Scan(&suppliers[i].ID); err != nil { return errs.NewInternalError(errs.DatabaseError, "failed to scan supplier id", err) } suppliers[i].RequestID = requestID i++ } return nil } func (r *supplierRepository) GetByRequestID(ctx context.Context, requestID uuid.UUID) ([]*model.Supplier, error) { query := r.qb.Select( "id", "request_id", "name", "email", "phone", "adress", "url", "created_at", ).From("suppliers").Where(sq.Eq{"request_id": requestID}).OrderBy("id") sqlQuery, args, err := query.ToSql() if err != nil { return nil, errs.NewInternalError(errs.DatabaseError, "failed to build query", err) } rows, err := r.pool.Query(ctx, sqlQuery, args...) if err != nil { return nil, errs.NewInternalError(errs.DatabaseError, "failed to get suppliers", err) } defer rows.Close() var suppliers []*model.Supplier for rows.Next() { s := &model.Supplier{} err := rows.Scan( &s.ID, &s.RequestID, &s.Name, &s.Email, &s.Phone, &s.Address, &s.URL, &s.CreatedAt, ) if err != nil { return nil, errs.NewInternalError(errs.DatabaseError, "failed to scan supplier", err) } suppliers = append(suppliers, s) } return suppliers, nil } func (r *supplierRepository) DeleteByRequestID(ctx context.Context, requestID uuid.UUID) error { query := r.qb.Delete("suppliers").Where(sq.Eq{"request_id": requestID}) sqlQuery, args, err := query.ToSql() if err != nil { return errs.NewInternalError(errs.DatabaseError, "failed to build query", err) } _, err = r.pool.Exec(ctx, sqlQuery, args...) if err != nil { return errs.NewInternalError(errs.DatabaseError, "failed to delete suppliers", err) } return nil }