Files
cloud-services/pkg/db/queries/subscriptions.go

157 lines
4.2 KiB
Go

package queries
import (
"time"
"fiskerinc.com/modules/common"
"fiskerinc.com/modules/validator"
"github.com/go-pg/pg/v10/orm"
"github.com/google/uuid"
"github.com/pkg/errors"
)
type SubscriptionsInterface interface {
Delete(req *SubscriptionDeleteRequest) (orm.Result, error)
Insert(subtype *common.Subscription) (orm.Result, error)
Update(subtype *common.Subscription) (orm.Result, error)
Select(filter *common.Subscription) ([]common.Subscription, error)
Load(subtype *common.Subscription) error
Count(filter *common.Subscription) (int, error)
Create(subtype *common.SubscriptionType, carToDriver *common.CarToDriver) (*common.Subscription, error)
}
type Subscriptions struct {
QueryBase
}
// Select returns list of drivers
func (s *Subscriptions) Select(filter *common.Subscription) ([]common.Subscription, error) {
subs := []common.Subscription{}
query := s.GetDBConn().Model(&subs)
s.selectFilter(query, filter)
err := query.Select()
return subs, errors.WithStack(err)
}
func (s *Subscriptions) selectFilter(query *orm.Query, filter *common.Subscription) {
if filter.ID != 0 {
query.Where("id = ?", filter.ID)
}
if filter.SubscriptionTypeID != uuid.Nil {
query.Where("subscription_type_id = ?", filter.SubscriptionTypeID)
}
if filter.CarToDriverID != 0 {
query.Where("car_to_driver_id = ?", filter.CarToDriverID)
}
if filter.Name != "" {
query.Where("name = ?", filter.Name)
}
if filter.Name != "" {
query.Where("destination = ?", filter.Destination)
}
}
func (s *Subscriptions) Insert(subtype *common.Subscription) (orm.Result, error) {
return s.insert(subtype)
}
func (s *Subscriptions) Update(subtype *common.Subscription) (orm.Result, error) {
err := s.validateSubID(subtype)
if err != nil {
return nil, err
}
return s.GetDBConn().Model(subtype).Column("subscription_type_id", "car_to_driver_id", "name", "destination", "expires").WherePK().Update()
}
func (s *Subscriptions) Delete(req *SubscriptionDeleteRequest) (orm.Result, error) {
if req.ID > 0 {
return s.deleteByID(&common.Subscription{ID: req.ID})
}
return s.deleteRequest(req)
}
func (s *Subscriptions) deleteByID(sub *common.Subscription) (orm.Result, error) {
err := s.validateSubID(sub)
if err != nil {
return nil, err
}
return s.resultWithStack(s.GetDBConn().Model(sub).WherePK().Delete())
}
func (s *Subscriptions) deleteRequest(req *SubscriptionDeleteRequest) (orm.Result, error) {
err := validator.ValidateStruct(req)
if err != nil {
return nil, errors.WithStack(err)
}
return s.resultWithStack(s.GetDBConn().Model((*common.Subscription)(nil)).Exec(`DELETE FROM "subscriptions" AS "subs" WHERE (subs.id IN (SELECT subs2.id FROM "subscriptions" AS "subs2" JOIN car_to_drivers AS c ON (c.id = subs2.car_to_driver_id) WHERE (c.vin = ? AND subs2.name = ?)))`, req.VIN, req.Name))
}
func (s *Subscriptions) Load(sub *common.Subscription) error {
query := s.GetDBConn().Model(sub)
if sub.ID != 0 {
query.WherePK()
} else if sub.SubscriptionTypeID != uuid.Nil && sub.CarToDriverID != 0 {
query.Where("subscription_type_id = ?subscription_type_id AND driver_id = ?car_to_driver_id")
} else {
return errors.New("no id or subscription_type_id, driver_id")
}
return errors.WithStack(query.Select())
}
func (s *Subscriptions) Count(filter *common.Subscription) (int, error) {
query := s.GetDBConn().Model((*common.Subscription)(nil))
s.selectFilter(query, filter)
count, err := query.Count()
return count, errors.WithStack(err)
}
func (s *Subscriptions) validateSubID(subtype *common.Subscription) error {
if subtype.ID == 0 {
return errors.WithStack(&validator.FieldError{
ErrorMsg: "ID required",
})
}
return nil
}
func (s *Subscriptions) Create(subtype *common.SubscriptionType, carToDriver *common.CarToDriver) (*common.Subscription, error) {
sub := common.Subscription{
Name: subtype.Name,
Destination: subtype.Destination,
CarToDriverID: carToDriver.ID,
SubscriptionTypeID: subtype.ID,
Expires: time.Now().Add(subtype.GetDuration()),
}
_, err := s.Insert(&sub)
if err != nil {
return nil, err
}
return &sub, nil
}
type SubscriptionDeleteRequest struct {
ID int64 `json:"id"`
Name string `json:"name" validate:"required,max=256"`
VIN string `json:"vin" validate:"required,vin"`
}