mirror of
https://github.com/jlelse/GoBlog
synced 2024-07-27 00:25:55 +00:00
67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
func (db *database) shortenPath(p string) (string, error) {
|
|
if p == "" {
|
|
return "", errors.New("empty path")
|
|
}
|
|
|
|
db.sp.Lock()
|
|
defer db.sp.Unlock()
|
|
|
|
result, err := db.shortenPathTransaction(p)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (db *database) shortenPathTransaction(p string) (string, error) {
|
|
tx, err := db.Begin()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer tx.Rollback()
|
|
|
|
var id int64
|
|
err = tx.QueryRow("select id from shortpath where path = @path", sql.Named("path", p)).Scan(&id)
|
|
if err == sql.ErrNoRows {
|
|
// Path doesn't exist, insert new entry with the lowest available id
|
|
err = tx.QueryRow(`
|
|
WITH RECURSIVE ids(n) AS (
|
|
SELECT 1
|
|
UNION ALL
|
|
SELECT n + 1 FROM ids
|
|
WHERE n < (SELECT COALESCE(MAX(id), 0) + 1 FROM shortpath)
|
|
)
|
|
INSERT INTO shortpath (id, path)
|
|
VALUES (
|
|
(SELECT n FROM ids
|
|
LEFT JOIN shortpath s ON ids.n = s.id
|
|
WHERE s.id IS NULL
|
|
ORDER BY n
|
|
LIMIT 1),
|
|
?
|
|
)
|
|
RETURNING id
|
|
`, p).Scan(&id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
} else if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if err = tx.Commit(); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return fmt.Sprintf("/s/%x", id), nil
|
|
}
|