package infrastructure import ( "database/sql" "code.osinet.fr/fgm/kurz/domain" _ "github.com/go-sql-driver/mysql" ) type MySQLShortURLRepository struct { DB *sql.DB } type MySQLTargetURLRepository struct { DB *sql.DB } func (sr MySQLShortURLRepository) GetTarget(su domain.ShortURL) (domain.TargetURL, error) { var tu domain.TargetURL row := sr.DB.QueryRow(` SELECT map.url FROM map WHERE map.hash = ? `, su.URL) err := row.Scan(&tu.URL) switch err { case sql.ErrNoRows: err = domain.MakeError(domain.ShortNotFound, string(su.URL)) case nil: break default: err = domain.MakeError(domain.StorageReadError, "") } return tu, err } func (tr MySQLTargetURLRepository) GetShort(tu domain.TargetURL) (su domain.ShortURL, isNew bool, err error) { // TODO future versions may have multiple shorts for a target, and choose a // specific short based on the domain and Kurz user. For now just ensure we // don't get more than one. row := tr.DB.QueryRow(` SELECT map.hash FROM map LIMIT 1 `) err = row.Scan(&su.URL) switch err { case sql.ErrNoRows: // If it doesn't exist, attempt to create it. su, err = domain.NewUnspecifiedShortURL(tu) if err != nil { // Creation failed. return su, false, err } _, err = tr.DB.Exec(` INSERT INTO map(hash, url, date1, date2, date3, refcount) VALUES (?, ?, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 0) `, su.URL, tu.URL) if err != nil { err = domain.MakeError(domain.StorageWriteError, "storing new mapping") } isNew = true case nil: break default: err = domain.MakeError(domain.StorageReadError, "looking for mapping") } return }