github.com/gudimz/urlShortener@v0.0.0-20230129195305-c8ee33059a67/internal/storage/shorten/postgres.go (about) 1 package shorten 2 3 import ( 4 "context" 5 "fmt" 6 "github.com/gudimz/urlShortener/internal/db/postgres" 7 "github.com/gudimz/urlShortener/internal/model" 8 "github.com/gudimz/urlShortener/pkg/logging" 9 "strings" 10 "time" 11 ) 12 13 const ( 14 queryToCreate = ` 15 INSERT INTO shorten_urls 16 (short_url, origin_url, visits, date_created, date_updated) 17 VALUES 18 ($1, $2, $3, $4, $5) 19 ` 20 queryToGetAll = ` 21 SELECT 22 short_url, origin_url, visits, date_created, date_updated 23 FROM 24 shorten_urls 25 ` 26 queryToGetByShortUrl = queryToGetAll + ` WHERE short_url = $1` 27 queryToDeleteByShortUrl = `DELETE FROM shorten_urls WHERE short_url = $1` 28 queryToUpdateByShortUrl = ` 29 UPDATE shorten_urls 30 SET visits = visits + 1, date_updated = $1 31 WHERE short_url = $2 32 ` 33 ) 34 35 type storage struct { 36 db postgres.Client 37 logger *logging.Logger 38 } 39 40 func NewStorage(db postgres.Client, logger *logging.Logger) *storage { 41 return &storage{ 42 db: db, 43 logger: logger, 44 } 45 } 46 47 func queryForLogger(q string) string { 48 return strings.ReplaceAll(strings.ReplaceAll(q, "\t", ""), "\n", " ") 49 } 50 51 func (p *storage) CreateShorten(ctx context.Context, ms model.Shorten) error { 52 q := queryToCreate 53 dbm := dbShortenFromModel(ms) 54 p.logger.Trace(fmt.Sprintf("SQL Query: %s", queryForLogger(q))) 55 _, err := p.db.Exec( 56 ctx, 57 q, 58 dbm.ShortUrl, 59 dbm.OriginUrl, 60 dbm.Visits, 61 dbm.DateCreated, 62 dbm.DateUpdated) 63 if err != nil { 64 p.logger.Error(err) 65 return err 66 } 67 return nil 68 } 69 70 func (p *storage) GetShorten(ctx context.Context, shortUrl string) (*model.Shorten, error) { 71 q := queryToGetByShortUrl 72 p.logger.Trace(fmt.Sprintf("SQL Query: %s", queryForLogger(q))) 73 var dbShorten model.DbShorten 74 err := p.db.QueryRow(ctx, q, shortUrl).Scan( 75 &dbShorten.ShortUrl, 76 &dbShorten.OriginUrl, 77 &dbShorten.Visits, 78 &dbShorten.DateCreated, 79 &dbShorten.DateUpdated) 80 if err != nil { 81 p.logger.Error(err) 82 return nil, err 83 } 84 return modelFromDbShorten(dbShorten), nil 85 } 86 87 func (p *storage) DeleteShorten(ctx context.Context, shortUrl string) (int64, error) { 88 q := queryToDeleteByShortUrl 89 p.logger.Trace(fmt.Sprintf("SQL Query: %s", queryForLogger(q))) 90 res, err := p.db.Exec(ctx, q, shortUrl) 91 if err != nil { 92 p.logger.Error(err) 93 return 0, err 94 } 95 count := res.RowsAffected() 96 return count, nil 97 } 98 99 func (p *storage) UpdateShorten(ctx context.Context, shortUrl string) error { 100 q := queryToUpdateByShortUrl 101 p.logger.Trace(fmt.Sprintf("SQL Query: %s", queryForLogger(q))) 102 _, err := p.db.Exec(ctx, q, time.Now().UTC(), shortUrl) 103 if err != nil { 104 p.logger.Error(err) 105 return err 106 } 107 return nil 108 } 109 110 func dbShortenFromModel(shorten model.Shorten) model.DbShorten { 111 return model.DbShorten{ 112 ShortUrl: shorten.ShortUrl, 113 OriginUrl: shorten.OriginUrl, 114 Visits: shorten.Visits, 115 DateCreated: shorten.DateCreated, 116 DateUpdated: shorten.DateUpdated, 117 } 118 } 119 120 func modelFromDbShorten(dbShorten model.DbShorten) *model.Shorten { 121 return &model.Shorten{ 122 ShortUrl: dbShorten.ShortUrl, 123 OriginUrl: dbShorten.OriginUrl, 124 Visits: dbShorten.Visits, 125 DateCreated: dbShorten.DateCreated, 126 DateUpdated: dbShorten.DateUpdated, 127 } 128 }