2024-12-19 16:14:41 -05:00
|
|
|
package callstore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-12-27 13:14:45 -05:00
|
|
|
"fmt"
|
2024-12-19 16:14:41 -05:00
|
|
|
|
|
|
|
"dynatron.me/x/stillbox/internal/common"
|
|
|
|
"dynatron.me/x/stillbox/internal/jsontypes"
|
|
|
|
|
|
|
|
"dynatron.me/x/stillbox/pkg/calls"
|
|
|
|
"dynatron.me/x/stillbox/pkg/database"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/jackc/pgx/v5"
|
2024-12-27 13:14:45 -05:00
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
2024-12-19 16:14:41 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type Store interface {
|
|
|
|
// CallAudio returns a CallAudio struct
|
|
|
|
CallAudio(ctx context.Context, id uuid.UUID) (*calls.CallAudio, error)
|
|
|
|
|
|
|
|
// Calls gets paginated Calls.
|
|
|
|
Calls(ctx context.Context, p CallsParams) (calls []database.ListCallsPRow, totalCount int, err error)
|
|
|
|
}
|
|
|
|
|
|
|
|
type store struct {
|
|
|
|
}
|
|
|
|
|
2024-12-28 18:32:13 -05:00
|
|
|
func NewStore() *store {
|
2024-12-19 16:14:41 -05:00
|
|
|
return new(store)
|
|
|
|
}
|
|
|
|
|
|
|
|
type storeCtxKey string
|
|
|
|
|
|
|
|
const StoreCtxKey storeCtxKey = "store"
|
|
|
|
|
|
|
|
func CtxWithStore(ctx context.Context, s Store) context.Context {
|
|
|
|
return context.WithValue(ctx, StoreCtxKey, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func FromCtx(ctx context.Context) Store {
|
|
|
|
s, ok := ctx.Value(StoreCtxKey).(Store)
|
|
|
|
if !ok {
|
2024-12-28 18:32:13 -05:00
|
|
|
return NewStore()
|
2024-12-19 16:14:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *store) CallAudio(ctx context.Context, id uuid.UUID) (*calls.CallAudio, error) {
|
|
|
|
db := database.FromCtx(ctx)
|
|
|
|
|
|
|
|
dbCall, err := db.GetCallAudioByID(ctx, id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &calls.CallAudio{
|
|
|
|
CallDate: jsontypes.Time(dbCall.CallDate.Time),
|
|
|
|
AudioName: dbCall.AudioName,
|
|
|
|
AudioType: dbCall.AudioType,
|
|
|
|
AudioBlob: dbCall.AudioBlob,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type CallsParams struct {
|
|
|
|
common.Pagination
|
|
|
|
Direction *common.SortDirection `json:"dir"`
|
|
|
|
|
2024-12-27 13:14:45 -05:00
|
|
|
Start *jsontypes.Time `json:"start"`
|
|
|
|
End *jsontypes.Time `json:"end"`
|
|
|
|
TagsAny []string `json:"tagsAny"`
|
|
|
|
TagsNot []string `json:"tagsNot"`
|
|
|
|
TGFilter *string `json:"tgFilter"`
|
|
|
|
AtLeastSeconds *float32 `json:"atLeastSeconds"`
|
2024-12-19 16:14:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *store) Calls(ctx context.Context, p CallsParams) (rows []database.ListCallsPRow, totalCount int, err error) {
|
|
|
|
db := database.FromCtx(ctx)
|
|
|
|
|
|
|
|
offset, perPage := p.Pagination.OffsetPerPage(100)
|
|
|
|
par := database.ListCallsPParams{
|
|
|
|
Start: p.Start.PGTypeTSTZ(),
|
|
|
|
End: p.End.PGTypeTSTZ(),
|
|
|
|
TagsAny: p.TagsAny,
|
|
|
|
TagsNot: p.TagsNot,
|
|
|
|
Offset: offset,
|
|
|
|
PerPage: perPage,
|
|
|
|
Direction: p.Direction.DirString(common.DirAsc),
|
2024-12-27 13:14:45 -05:00
|
|
|
TGFilter: p.TGFilter,
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.AtLeastSeconds != nil {
|
|
|
|
var n pgtype.Numeric
|
|
|
|
if err := n.Scan(fmt.Sprint(*p.AtLeastSeconds * 1000)); err != nil {
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
par.LongerThan = n
|
2024-12-19 16:14:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
txErr := db.InTx(ctx, func(db database.Store) error {
|
|
|
|
var err error
|
|
|
|
count, err = db.ListCallsCount(ctx, database.ListCallsCountParams{
|
2024-12-29 13:27:17 -05:00
|
|
|
Start: par.Start,
|
|
|
|
End: par.End,
|
|
|
|
TagsAny: par.TagsAny,
|
|
|
|
TagsNot: par.TagsNot,
|
|
|
|
TGFilter: par.TGFilter,
|
|
|
|
LongerThan: par.LongerThan,
|
2024-12-19 16:14:41 -05:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-12-29 13:27:17 -05:00
|
|
|
if offset > int32(count) {
|
|
|
|
return fmt.Errorf("requested page out of range")
|
|
|
|
}
|
|
|
|
|
2024-12-19 16:14:41 -05:00
|
|
|
rows, err = db.ListCallsP(ctx, par)
|
|
|
|
return err
|
|
|
|
}, pgx.TxOptions{})
|
|
|
|
if txErr != nil {
|
|
|
|
return nil, 0, txErr
|
|
|
|
}
|
|
|
|
|
|
|
|
return rows, int(count), err
|
|
|
|
}
|