123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /*
- The "strategy" package in Kurz provides the aliasing strategies.
- Files
- - strategy.go contains the interface and base implementation
- - strategies.go contains the strategy instances and utilities
- - manual.go contains the "manual" strategy
- - hexrcr32.go contains the "hexcrc32" strategy
- */
- package strategy
- import (
- "code.osinet.fr/fgm/kurz/storage"
- "code.osinet.fr/fgm/kurz/url"
- "log"
- "time"
- )
- /*
- AliasingStrategy defines the operations provided by the various aliasing implementations:
- The options parameter for Alias() MAY be used by some strategies, in which case they
- have to define their expectations about it.
- */
- type AliasingStrategy interface {
- Name() string // Return the name of the strategy object
- Alias(url *url.LongUrl, s storage.Storage, options ...interface{}) (url.ShortUrl, error) // Return the short URL (alias) for a given long (source) URL
- UseCount(storage storage.Storage) int // Return the number of short URLs (aliases) using this strategy.
- }
- type baseStrategy struct{}
- func (y baseStrategy) Name() string {
- return "base"
- }
- /*
- Make sure a longurl instance has a DB ID, allocating it if needed.
- For speed reasons, assumes nonzero IDs to be valid without checking.
- */
- func (y baseStrategy) ensureLongId(long *url.LongUrl, s storage.Storage) error {
- var err error
- var long_id int64
- // If long does not have an Id, check if it is already known.
- if long.Id == 0 {
- sql := `
- SELECT id
- FROM longurl
- WHERE url = ?
- `
- err = s.DB.QueryRow(sql, y.Name()).Scan(&long_id)
- if err != nil {
- long_id = 0
- // log.Printf("Failed querying database for long url %s: %v\n", long.Value, err)
- }
- sql = `
- INSERT INTO longurl(url)
- VALUES (?)
- `
- result, err := s.DB.Exec(sql, long.Value)
- if err != nil {
- log.Printf("Failed inserting long URL %s: %+v", long.Value, err)
- return err
- } else {
- long_id, _ = result.LastInsertId()
- }
- long.Id = long_id
- }
- return nil
- }
- func (y baseStrategy) Alias(long *url.LongUrl, s storage.Storage, options ...interface{}) (url.ShortUrl, error) {
- var short url.ShortUrl
- var sql string
- var err error
- err = y.ensureLongId(long, s)
- if err != nil {
- return short, err
- }
- /** TODO
- * - validate alias is available
- */
- short = url.ShortUrl{
- Value: long.Value,
- ShortFor: *long,
- Domain: long.Domain(),
- Strategy: y.Name(),
- SubmittedBy: storage.CurrentUser(),
- SubmittedOn: time.Now().UTC().Unix(),
- IsEnabled: true,
- }
- sql = `
- INSERT INTO shorturl(url, longurl, domain, strategy, submittedBy, submittedInfo, isEnabled)
- VALUES (?, ?, ?, ?, ?, ?, ?)
- `
- result, err := s.DB.Exec(sql, short.Value, short.ShortFor.Id, short.Domain, short.Strategy, short.SubmittedBy.Id, short.SubmittedOn, short.IsEnabled)
- if err != nil {
- log.Printf("Failed inserting short %s: %#v", short.Value, err)
- } else {
- short.Id, _ = result.LastInsertId()
- }
- return short, err
- }
- /**
- Any nonzero result is likely an error.
- */
- func (y baseStrategy) UseCount(s storage.Storage) int {
- sql := `
- SELECT COUNT(*)
- FROM shorturl
- WHERE strategy = ?
- `
- var count int
- err := s.DB.QueryRow(sql, y.Name()).Scan(&count)
- if err != nil {
- count = 0
- log.Printf("Failed querying database for base strategy use count: %v\n", err)
- }
- return count
- }
|