2022-05-09 12:52:18 +00:00
|
|
|
package db
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
2022-05-15 22:27:52 +00:00
|
|
|
"time"
|
2022-05-09 12:52:18 +00:00
|
|
|
|
|
|
|
_ "embed"
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
_ "github.com/go-sql-driver/mysql"
|
2022-05-09 12:52:18 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
|
|
|
|
"git.kapelle.org/niklas/s3share/internal/types"
|
|
|
|
)
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
//go:embed setup.sql
|
2022-05-09 12:52:18 +00:00
|
|
|
var setupSql string
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
type sqlDB struct {
|
2022-05-09 12:52:18 +00:00
|
|
|
db *sql.DB
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
func NewSQLDB(dataSourceName string) (DB, error) {
|
|
|
|
db, err := sql.Open("mysql", dataSourceName)
|
2022-05-09 12:52:18 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
// https://github.com/go-sql-driver/mysql#important-settings
|
|
|
|
db.SetConnMaxLifetime(time.Minute * 3)
|
|
|
|
db.SetMaxOpenConns(10)
|
|
|
|
db.SetMaxIdleConns(10)
|
|
|
|
|
|
|
|
// Connect and check the server version
|
|
|
|
var version string
|
|
|
|
db.QueryRow("SELECT VERSION()").Scan(&version)
|
|
|
|
logrus.Info("DB Version:", version)
|
|
|
|
|
2022-05-09 12:52:18 +00:00
|
|
|
_, err = db.Exec(setupSql)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
return &sqlDB{
|
2022-05-09 12:52:18 +00:00
|
|
|
db: db,
|
|
|
|
}, nil
|
2022-05-15 22:27:52 +00:00
|
|
|
|
2022-05-09 12:52:18 +00:00
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
func (db *sqlDB) GetShare(ctx context.Context, slug string) (*types.Share, error) {
|
2022-05-09 12:52:18 +00:00
|
|
|
res, err := db.db.QueryContext(ctx, "SELECT slug, objKey FROM shares WHERE slug = ?", slug)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !res.Next() {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var share types.Share
|
|
|
|
|
|
|
|
err = res.Scan(&share.Slug, &share.Key)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &share, nil
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
func (db *sqlDB) CreateShare(ctx context.Context, share *types.Share) error {
|
2022-05-09 12:52:18 +00:00
|
|
|
_, err := db.db.ExecContext(ctx, "INSERT INTO shares (slug, objKey) VALUES (?, ?)", share.Slug, share.Key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
func (db *sqlDB) DeleteShare(ctx context.Context, slug string) error {
|
2022-06-03 12:27:40 +00:00
|
|
|
result, err := db.db.ExecContext(ctx, "DELETE FROM shares WHERE slug = ?", slug)
|
2022-05-09 12:52:18 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-06-03 12:27:40 +00:00
|
|
|
|
|
|
|
rowsAffected, err := result.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if rowsAffected == 0 {
|
|
|
|
return types.ErrShareNotFound
|
|
|
|
}
|
|
|
|
|
2022-05-09 12:52:18 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
func (db *sqlDB) GetAllShares(ctx context.Context) ([]*types.Share, error) {
|
2022-05-14 21:25:50 +00:00
|
|
|
res, err := db.db.QueryContext(ctx, "SELECT slug, objKey FROM shares")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var shares []*types.Share
|
|
|
|
|
|
|
|
for res.Next() {
|
|
|
|
var share types.Share
|
|
|
|
|
|
|
|
err = res.Scan(&share.Slug, &share.Key)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
shares = append(shares, &share)
|
|
|
|
}
|
|
|
|
|
|
|
|
return shares, nil
|
|
|
|
}
|
|
|
|
|
2022-05-15 22:27:52 +00:00
|
|
|
func (db *sqlDB) Close() error {
|
2022-05-09 12:52:18 +00:00
|
|
|
return db.db.Close()
|
|
|
|
}
|