Update link repository
Add timeout to contexts. Add method for retrieving all links.
This commit is contained in:
parent
99be0824cd
commit
2eea43d973
1 changed files with 76 additions and 6 deletions
|
|
@ -7,11 +7,13 @@ import (
|
||||||
"github.com/jackc/pgx/v4"
|
"github.com/jackc/pgx/v4"
|
||||||
"github.com/jackc/pgx/v4/pgxpool"
|
"github.com/jackc/pgx/v4/pgxpool"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Repository interface {
|
type Repository interface {
|
||||||
Save(link *Link) error
|
Save(link *Link) error
|
||||||
FindById(id string) (*Link, error)
|
FindById(id string) (*Link, error)
|
||||||
|
FindAll(limit int, offset int) ([]Link, error)
|
||||||
DeleteById(id string) error
|
DeleteById(id string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -20,7 +22,9 @@ type PgRepository struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PgRepository) Save(link *Link) error {
|
func (r *PgRepository) Save(link *Link) error {
|
||||||
ctx := context.Background()
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
tx, err := r.pool.Begin(ctx)
|
tx, err := r.pool.Begin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -45,7 +49,9 @@ func (r *PgRepository) Save(link *Link) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *PgRepository) FindById(id string) (*Link, error) {
|
func (r *PgRepository) FindById(id string) (*Link, error) {
|
||||||
ctx := context.Background()
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
tx, err := r.pool.Begin(ctx)
|
tx, err := r.pool.Begin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -74,8 +80,63 @@ func (r *PgRepository) FindById(id string) (*Link, error) {
|
||||||
return entity, nil
|
return entity, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *PgRepository) FindAll(limit int, offset int) ([]Link, error) {
|
||||||
|
if limit < 0 {
|
||||||
|
return nil, errors.New("limit can't be negative")
|
||||||
|
}
|
||||||
|
if offset < 0 {
|
||||||
|
return nil, errors.New("offset can't be negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tx, err := r.pool.Begin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sql := `
|
||||||
|
SELECT id, name, redirect_url, creation_time
|
||||||
|
FROM links
|
||||||
|
LIMIT $1
|
||||||
|
OFFSET $2
|
||||||
|
`
|
||||||
|
|
||||||
|
rows, err := tx.Query(ctx, sql, limit, offset)
|
||||||
|
if err != nil {
|
||||||
|
_ = tx.Rollback(ctx)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
links := make([]Link, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
link, err := mapRowToEntity(rows)
|
||||||
|
if err != nil {
|
||||||
|
_ = tx.Rollback(ctx)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
links = append(links, *link)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = rows.Err(); err != nil {
|
||||||
|
_ = tx.Rollback(ctx)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = tx.Commit(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return links, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *PgRepository) DeleteById(id string) error {
|
func (r *PgRepository) DeleteById(id string) error {
|
||||||
ctx := context.Background()
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
tx, err := r.pool.Begin(ctx)
|
tx, err := r.pool.Begin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -98,14 +159,23 @@ func (r *PgRepository) DeleteById(id string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapRowToEntity(r pgx.Row) (*Link, error) {
|
func mapRowToEntity(r interface{}) (*Link, error) {
|
||||||
var entity Link
|
var entity Link
|
||||||
var urlStr string
|
var urlStr string
|
||||||
var t pgtype.Timestamp
|
var t pgtype.Timestamp
|
||||||
|
|
||||||
if err := r.Scan(&entity.Id, &entity.Name, &urlStr, &t); err != nil {
|
switch v := r.(type) {
|
||||||
|
case pgx.Row:
|
||||||
|
if err := v.Scan(&entity.Id, &entity.Name, &urlStr, &t); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
case pgx.Rows:
|
||||||
|
if err := v.Scan(&entity.Id, &entity.Name, &urlStr, &t); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New("unsupported type")
|
||||||
|
}
|
||||||
|
|
||||||
u, err := url.Parse(urlStr)
|
u, err := url.Parse(urlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue