2020-12-22 21:15:29 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"errors"
|
2021-11-13 22:33:21 +00:00
|
|
|
|
|
|
|
"github.com/mattn/go-sqlite3"
|
2020-12-22 21:15:29 +00:00
|
|
|
)
|
|
|
|
|
2021-06-06 12:39:42 +00:00
|
|
|
func (db *database) shortenPath(p string) (string, error) {
|
2020-12-22 21:15:29 +00:00
|
|
|
if p == "" {
|
|
|
|
return "", errors.New("empty path")
|
|
|
|
}
|
2021-11-09 09:50:03 +00:00
|
|
|
spi, err, _ := db.sp.Do(p, func() (interface{}, error) {
|
|
|
|
// Check if already cached
|
|
|
|
if spi, ok := db.spc.Load(p); ok {
|
|
|
|
return spi.(string), nil
|
2020-12-22 21:15:29 +00:00
|
|
|
}
|
2021-11-09 09:50:03 +00:00
|
|
|
// Insert in case it isn't shortened yet
|
2021-11-14 06:58:49 +00:00
|
|
|
_, err := db.exec(`
|
|
|
|
insert or rollback into shortpath (id, path)
|
|
|
|
values (
|
|
|
|
-- next available id (reuse skipped ids due to bug)
|
|
|
|
(select min(id) + 1 from (select id from shortpath union all select 0) where id + 1 not in (select id from shortpath)),
|
|
|
|
@path
|
|
|
|
)`, sql.Named("path", p))
|
2021-11-09 09:50:03 +00:00
|
|
|
if err != nil {
|
2021-11-14 06:58:49 +00:00
|
|
|
if no, ok := err.(sqlite3.Error); !ok || sqlite3.ErrNo(no.ExtendedCode) != sqlite3.ErrNo(sqlite3.ErrConstraintUnique) {
|
|
|
|
// Some other error than unique constraint violation because path is already shortened
|
2021-11-13 22:33:21 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2021-11-09 09:50:03 +00:00
|
|
|
}
|
|
|
|
// Query short path
|
|
|
|
row, err := db.queryRow("select printf('/s/%x', id) from shortpath where path = @path", sql.Named("path", p))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var sp string
|
|
|
|
err = row.Scan(&sp)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// Cache result
|
|
|
|
db.spc.Store(p, sp)
|
|
|
|
return sp, nil
|
2021-07-03 10:11:57 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
2020-12-22 21:15:29 +00:00
|
|
|
}
|
2021-11-09 09:50:03 +00:00
|
|
|
return spi.(string), nil
|
2020-12-22 21:15:29 +00:00
|
|
|
}
|