2020-05-14 10:20:05 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-11-15 15:52:03 +00:00
|
|
|
"database/sql"
|
2021-08-11 08:09:22 +00:00
|
|
|
"errors"
|
2020-05-14 10:20:05 +00:00
|
|
|
"log"
|
2021-08-11 08:09:22 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2020-11-15 15:52:03 +00:00
|
|
|
|
|
|
|
"github.com/lopezator/migrator"
|
2020-05-14 10:20:05 +00:00
|
|
|
)
|
|
|
|
|
2021-08-11 08:09:22 +00:00
|
|
|
func (a *app) openDatabase() (err error) {
|
|
|
|
if a.config.DBPath == "" {
|
|
|
|
return errors.New("empty database path")
|
|
|
|
}
|
|
|
|
_ = os.MkdirAll(filepath.Dir(a.config.DBPath), 0644)
|
|
|
|
a.database, err = sql.Open("sqlite3", a.config.DBPath+"?cache=shared&mode=rwc&_journal_mode=WAL&_busy_timeout=100")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
a.shutdown.Add(func() {
|
|
|
|
_ = a.database.Close()
|
|
|
|
log.Println("Closed database")
|
|
|
|
})
|
|
|
|
a.migrateDatabase()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *app) migrateDatabase() {
|
|
|
|
a.write.Lock()
|
|
|
|
defer a.write.Unlock()
|
2020-11-15 15:52:03 +00:00
|
|
|
m, err := migrator.New(
|
|
|
|
migrator.Migrations(
|
|
|
|
&migrator.Migration{
|
|
|
|
Name: "00001",
|
|
|
|
Func: func(tx *sql.Tx) error {
|
|
|
|
_, err := tx.Exec(`
|
|
|
|
drop table if exists gorp_migrations;
|
|
|
|
create table if not exists redirect(slug text not null primary key, url text not null, type text not null default 'url', hits integer default 0 not null);
|
|
|
|
insert or replace into redirect (slug, url) values ('source', 'https://git.jlel.se/jlelse/GoShort');
|
|
|
|
`)
|
|
|
|
return err
|
|
|
|
},
|
2020-05-14 10:20:05 +00:00
|
|
|
},
|
2020-11-15 15:52:03 +00:00
|
|
|
),
|
|
|
|
)
|
2020-05-14 10:20:05 +00:00
|
|
|
if err != nil {
|
2020-11-15 15:52:03 +00:00
|
|
|
log.Fatal(err.Error())
|
|
|
|
return
|
|
|
|
}
|
2021-08-11 08:09:22 +00:00
|
|
|
if err := m.Migrate(a.database); err != nil {
|
2020-11-15 15:52:03 +00:00
|
|
|
log.Fatal(err.Error())
|
|
|
|
return
|
2020-05-14 10:20:05 +00:00
|
|
|
}
|
|
|
|
}
|
2021-08-11 08:09:22 +00:00
|
|
|
|
|
|
|
const (
|
|
|
|
typUrl = "url"
|
|
|
|
typText = "text"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (a *app) insertRedirect(slug string, url string, typ string) error {
|
|
|
|
a.write.Lock()
|
|
|
|
defer a.write.Unlock()
|
|
|
|
_, err := a.database.Exec("INSERT INTO redirect (slug, url, type) VALUES (?, ?, ?)", slug, url, typ)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *app) deleteSlug(slug string) error {
|
|
|
|
a.write.Lock()
|
|
|
|
defer a.write.Unlock()
|
|
|
|
_, err := a.database.Exec("DELETE FROM redirect WHERE slug = ?", slug)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *app) increaseHits(slug string) {
|
|
|
|
go func() {
|
|
|
|
a.write.Lock()
|
|
|
|
defer a.write.Unlock()
|
|
|
|
_, _ = a.database.Exec("UPDATE redirect SET hits = hits + 1 WHERE slug = ?", slug)
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *app) slugExists(slug string) (exists bool, err error) {
|
|
|
|
err = a.database.QueryRow("SELECT EXISTS(SELECT 1 FROM redirect WHERE slug = ?)", slug).Scan(&exists)
|
|
|
|
return
|
|
|
|
}
|