Add PostgreSQL, user/squad management, remove private domains from docs
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
type WizardData map[string]any
|
||||
|
||||
type AdminWizard struct {
|
||||
AdminID int64
|
||||
Step string
|
||||
Data WizardData
|
||||
}
|
||||
|
||||
func (d *DB) GetWizard(ctx context.Context, adminID int64) (*AdminWizard, error) {
|
||||
row := d.pool.QueryRow(ctx, `
|
||||
SELECT admin_telegram_id, step, data
|
||||
FROM admin_wizard WHERE admin_telegram_id = $1`, adminID)
|
||||
|
||||
var w AdminWizard
|
||||
var raw []byte
|
||||
if err := row.Scan(&w.AdminID, &w.Step, &raw); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if len(raw) > 0 {
|
||||
_ = json.Unmarshal(raw, &w.Data)
|
||||
}
|
||||
if w.Data == nil {
|
||||
w.Data = WizardData{}
|
||||
}
|
||||
return &w, nil
|
||||
}
|
||||
|
||||
func (d *DB) SetWizard(ctx context.Context, adminID int64, step string, data WizardData) error {
|
||||
raw, _ := json.Marshal(data)
|
||||
_, err := d.pool.Exec(ctx, `
|
||||
INSERT INTO admin_wizard (admin_telegram_id, step, data, updated_at)
|
||||
VALUES ($1, $2, $3, NOW())
|
||||
ON CONFLICT (admin_telegram_id) DO UPDATE SET
|
||||
step = EXCLUDED.step,
|
||||
data = EXCLUDED.data,
|
||||
updated_at = NOW()`,
|
||||
adminID, step, raw)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *DB) ClearWizard(ctx context.Context, adminID int64) error {
|
||||
_, err := d.pool.Exec(ctx, `DELETE FROM admin_wizard WHERE admin_telegram_id = $1`, adminID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (w WizardData) String(key string) string {
|
||||
v, _ := w[key].(string)
|
||||
return v
|
||||
}
|
||||
|
||||
func (w WizardData) Int(key string) int {
|
||||
switch v := w[key].(type) {
|
||||
case float64:
|
||||
return int(v)
|
||||
case int:
|
||||
return v
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (w WizardData) StringSlice(key string) []string {
|
||||
raw, ok := w[key].([]any)
|
||||
if !ok {
|
||||
if ss, ok := w[key].([]string); ok {
|
||||
return ss
|
||||
}
|
||||
return nil
|
||||
}
|
||||
out := make([]string, 0, len(raw))
|
||||
for _, x := range raw {
|
||||
if s, ok := x.(string); ok {
|
||||
out = append(out, s)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (w WizardData) Set(key string, val any) {
|
||||
w[key] = val
|
||||
}
|
||||
|
||||
func (w WizardData) ToggleUUID(key, uuid string) {
|
||||
cur := w.StringSlice(key)
|
||||
for i, id := range cur {
|
||||
if id == uuid {
|
||||
cur = append(cur[:i], cur[i+1:]...)
|
||||
w[key] = cur
|
||||
return
|
||||
}
|
||||
}
|
||||
w[key] = append(cur, uuid)
|
||||
}
|
||||
|
||||
const (
|
||||
StepIdle = ""
|
||||
StepAwaitUsername = "await_username"
|
||||
StepAwaitDays = "await_days"
|
||||
StepPickExternalSquad = "pick_external"
|
||||
StepPickInternalSquads = "pick_internal"
|
||||
StepConfirm = "confirm"
|
||||
)
|
||||
|
||||
func DefaultExpireAt(days int) time.Time {
|
||||
if days <= 0 {
|
||||
days = 30
|
||||
}
|
||||
return time.Now().UTC().AddDate(0, 0, days)
|
||||
}
|
||||
Reference in New Issue
Block a user