2024-12-04 19:46:11 -04:00

190 lines
5.2 KiB
Go

package db
import (
"context"
"database/sql"
_ "embed"
"fmt"
"log/slog"
"time"
"git.maximotejeda.com/maximo/tgb-user/internal/application/core/domain"
_ "modernc.org/sqlite"
)
//go:embed schema.sql
var schema string
type Adapter struct {
db *sql.DB
log *slog.Logger
}
func NewAdapter(dataSourceURL string) (*Adapter, error) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
log := slog.Default().With("adapter", "db")
pragmas := "cache=shared&_foreign_keys=on&_busy_timeout=3000&_journal_mode=WAL"
db, err := sql.Open("sqlite", fmt.Sprintf("file:%s?%s", dataSourceURL, pragmas))
if err != nil {
return nil, fmt.Errorf("connecion error: %w", err)
}
err = db.PingContext(ctx)
if err != nil {
return nil, fmt.Errorf("ping error: %w", err)
}
db.SetConnMaxIdleTime(10 * time.Second)
CreateTables(db)
return &Adapter{db: db, log: log}, nil
}
// Schema
func CreateTables(db *sql.DB) {
_, err := db.Exec(schema)
if err != nil {
panic(err)
}
}
func (a Adapter) Create(ctx context.Context, req *domain.User) (bool, error) {
user := User{db: a.db, log: a.log}
ok, err := user.Create(ctx, req)
return ok, err
}
func (a Adapter) Get(ctx context.Context, id int64) (*domain.User, error) {
user := NewUser(a.db, a.log)
visit := NewVisits(a.db, a.log)
us, err := user.Get(ctx, id)
if err != nil {
return nil, err
}
_, err1 := visit.Add(ctx, id)
if err1 != nil {
fmt.Println(err1)
}
return us, err
}
func (a Adapter) Edit(ctx context.Context, us *domain.User) (bool, error) {
user := NewUser(a.db, a.log)
ok, err := user.Edit(ctx, *us)
return ok, err
}
func (a Adapter) Delete(ctx context.Context, id int64) (bool, error) {
// TODO db work
user := NewUser(a.db, a.log)
ok, err := user.Delete(ctx, id)
return ok, err
}
func (a Adapter) AddBot(ctx context.Context, tgb_id int64, botname string) (bool, error) {
bu := NewBotUser(a.db, a.log)
ok, err := bu.Add(ctx, tgb_id, botname)
return ok, err
}
func (a Adapter) DeleteBot(ctx context.Context, tgb_id int64, botname string) (bool, error) {
bu := NewBotUser(a.db, a.log)
ok, err := bu.Delete(ctx, tgb_id, botname)
return ok, err
}
func (a Adapter) GetBots(ctx context.Context, tgb_id int64) ([]*domain.Bot, error) {
bu := NewBotUser(a.db, a.log)
return bu.GetBots(ctx, tgb_id)
}
func (a Adapter) GetAllBotUsers(ctx context.Context, bot_name string) ([]*domain.User, error) {
bu := NewBotUser(a.db, a.log)
return bu.GetUsers(ctx, bot_name)
}
func (a Adapter) GetAllBots(ctx context.Context) ([]*domain.Bot, error) {
bu := NewBotUser(a.db, a.log)
return bu.GetAllBots(ctx)
}
// GetAccessRequest
// Returns all access request from a user
func (a Adapter) GetAccessRequest(ctx context.Context, tgbID int64) ([]*BotAccessRequest, error) {
bar := NewBotAccessRequest(a.db, a.log)
return bar.Get(ctx, tgbID)
}
// GetAllAccessRequest
// Returns all Access request from a bot
func (a Adapter) GetAllAccessRequest(ctx context.Context, botName string) ([]*BotAccessRequest, error) {
bar := NewBotAccessRequest(a.db, a.log)
return bar.GetAll(ctx, botName)
}
// CreateAccessRequest
// When user try get access to a restricted bot create a row in here
func (a Adapter) CreateAccessRequest(ctx context.Context, tgbID int64, botName string) (bool, error) {
bar := NewBotAccessRequest(a.db, a.log)
return bar.Add(ctx, tgbID, botName)
}
// GrantAccess
//
// If a row with user id and bot id is in db returns an object
func (a Adapter) GrantAccess(ctx context.Context, tgbID int64, botName string) (bool, error) {
bar := NewBotAccessRequest(a.db, a.log)
ok, err := bar.Delete(ctx, tgbID, botName)
if !ok {
return false, err
} else {
return a.AddBot(ctx, tgbID, botName)
}
}
// GetBannedBot
// get banned bots for a user
func (a Adapter) GetBannedBot(ctx context.Context, tgbID int64) ([]*BotBannedAccess, error) {
bba := NewBotBannedAccess(a.db, a.log)
return bba.Get(ctx, tgbID)
}
// GetAllBannedUsers
// get all users banned from a bot
func (a Adapter) GetAllBannedUsers(ctx context.Context, botName string) ([]*BotBannedAccess, error) {
bba := NewBotBannedAccess(a.db, a.log)
return bba.GetAll(ctx, botName)
}
// BanUser
// ban a user creating a row in db ban and removin access request and bot grants
func (a Adapter) BanUser(ctx context.Context, tgbID, until int64, botName string) (bool, error) {
bba := NewBotBannedAccess(a.db, a.log)
bar := NewBotAccessRequest(a.db, a.log)
if ok, err := bar.Delete(ctx, tgbID, botName); !ok {
a.log.Error("access request not deleted", "error", err)
}
if ok, err := a.DeleteBot(ctx, tgbID, botName); !ok {
a.log.Error("bot access not deleted", "error", err)
}
return bba.Add(ctx, tgbID, until, botName)
}
// UnBanUser
// Remove restriction from an user and create a access request
func (a Adapter) UnBanUser(ctx context.Context, tgbID int64, botName string) (bool, error) {
bba := NewBotBannedAccess(a.db, a.log)
bar := NewBotAccessRequest(a.db, a.log)
if ok, err := bba.Delete(ctx, tgbID, botName); !ok {
return false, err
} else {
return bar.Add(ctx, tgbID, botName)
}
}
// CreateBot
// create a new bot in db
func (a Adapter) CreateBot(ctx context.Context, botName string) (bool, error) {
bu := NewBotUser(a.db, a.log)
return bu.CreateBot(ctx, botName)
}