This is a simple URL shortener
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.5KB

  1. package db
  2. import (
  3. "errors"
  4. "github.com/asaskevich/govalidator"
  5. bolt "go.etcd.io/bbolt"
  6. )
  7. // DB is the struct that contains the connection with the Bold DB
  8. type DB struct {
  9. DB *bolt.DB
  10. }
  11. // ReadURL reads a shortened URL from the DB and returns the target URL for it
  12. func (d *DB) ReadURL(shortURL string) (fullURL string, err error) {
  13. if err := d.DB.View(func(tx *bolt.Tx) error {
  14. fullURL = string(tx.Bucket([]byte("urls")).Get([]byte(shortURL)))
  15. if fullURL == "" {
  16. return errors.New("the shortened URL wasn't found in the DB")
  17. }
  18. return nil
  19. }); err != nil {
  20. return "", err
  21. }
  22. return fullURL, nil
  23. }
  24. // AddURL adds a new URL to the DB
  25. func (d *DB) AddURL(shortURL string, longURL string) error {
  26. if shortURL == "" {
  27. return errors.New("the short URL can't be empty")
  28. }
  29. if longURL == "" {
  30. return errors.New("the long URL can't be empty")
  31. }
  32. if !govalidator.IsURL(longURL) {
  33. return errors.New("the long URL needs to be a valid URL")
  34. }
  35. return d.DB.Update(func(tx *bolt.Tx) error {
  36. b := tx.Bucket([]byte("urls"))
  37. if b == nil {
  38. return errors.New("the bucket urls doesn't exist")
  39. }
  40. if content := b.Get([]byte(shortURL)); content != nil {
  41. return errors.New("there's already an shortened URL with that URL")
  42. }
  43. if err := b.Put([]byte(shortURL), []byte(longURL)); err != nil {
  44. return err
  45. }
  46. return nil
  47. })
  48. }
  49. // Initialize creates the required bucket
  50. func (d *DB) Initialize() error {
  51. return d.DB.Update(func(tx *bolt.Tx) error {
  52. _, err := tx.CreateBucketIfNotExists([]byte("urls"))
  53. return err
  54. })
  55. }