func UpdateMulticastGroup(ctx context.Context, db sqlx.Execer, mg *MulticastGroup) error {
	mg.UpdatedAt = time.Now()
	res, err := db.Exec(`
		update
			multicast_group
		set
			updated_at = $2,
			mc_addr = $3,
			mc_nwk_s_key = $4,
			f_cnt = $5,
			group_type = $6,
			dr = $7,
			frequency = $8,
			ping_slot_period = $9,
			service_profile_id = $10,
			routing_profile_id = $11
		where
			id = $1`,
		mg.ID,
		mg.UpdatedAt,
		mg.MCAddr[:],
		mg.MCNwkSKey[:],
		mg.FCnt,
		mg.GroupType,
		mg.DR,
		mg.Frequency,
		mg.PingSlotPeriod,
		mg.ServiceProfileID,
		mg.RoutingProfileID,
	)
	if err != nil {
		return handlePSQLError(err, "update error")
	}
	ra, err := res.RowsAffected()
	if err != nil {
		return handlePSQLError(err, "get rows affected error")
	}
	if ra == 0 {
		return ErrDoesNotExist
	}
	log.WithFields(log.Fields{
		"id":     mg.ID,
		"ctx_id": ctx.Value(logging.ContextIDKey),
	}).Info("multicast-group updated")
	return nil
}
UpdateMulticastGroup updates the given multicast-grup.
package storage
import (
	"context"
	"time"
	"github.com/gofrs/uuid"
	"github.com/jmoiron/sqlx"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	"github.com/brocaar/chirpstack-network-server/v3/internal/logging"
	"github.com/brocaar/lorawan"
)
type MulticastGroupType string
const (
	MulticastGroupB MulticastGroupType = "B"
	MulticastGroupC MulticastGroupType = "C"
)
type MulticastGroup struct {
	ID               uuid.UUID          `db:"id"`
	CreatedAt        time.Time          `db:"created_at"`
	UpdatedAt        time.Time          `db:"updated_at"`
	MCAddr           lorawan.DevAddr    `db:"mc_addr"`
	MCNwkSKey        lorawan.AES128Key  `db:"mc_nwk_s_key"`
	FCnt             uint32             `db:"f_cnt"`
	GroupType        MulticastGroupType `db:"group_type"`
	DR               int                `db:"dr"`
	Frequency        uint32             `db:"frequency"`
	PingSlotPeriod   int                `db:"ping_slot_period"`
	RoutingProfileID uuid.UUID          `db:"routing_profile_id"`  
	ServiceProfileID uuid.UUID          `db:"service_profile_id"`
}
type MulticastQueueItem struct {
	ID                      int64          `db:"id"`
	CreatedAt               time.Time      `db:"created_at"`
	UpdatedAt               time.Time      `db:"updated_at"`
	ScheduleAt              time.Time      `db:"schedule_at"`
	EmitAtTimeSinceGPSEpoch *time.Duration `db:"emit_at_time_since_gps_epoch"`
	MulticastGroupID        uuid.UUID      `db:"multicast_group_id"`
	GatewayID               lorawan.EUI64  `db:"gateway_id"`
	FCnt                    uint32         `db:"f_cnt"`
	FPort                   uint8          `db:"f_port"`
	FRMPayload              []byte         `db:"frm_payload"`
	RetryAfter              *time.Time     `db:"retry_after"`
}
func (m MulticastQueueItem) Validate() error {
	if m.FPort == 0 {
		return ErrInvalidFPort
	}
	return nil
}
func CreateMulticastGroup(ctx context.Context, db sqlx.Execer, mg *MulticastGroup) error {
	now := time.Now()
	mg.CreatedAt = now
	mg.UpdatedAt = now
	if mg.ID == uuid.Nil {
		var err error
		mg.ID, err = uuid.NewV4()
		if err != nil {
			return errors.Wrap(err, "new uuid v4 error")
		}
	}
	_, err := db.Exec(`
		insert into multicast_group (
			id,
			created_at,
			updated_at,
			mc_addr,
			mc_nwk_s_key,
			f_cnt,
			group_type,
			dr,
			frequency,
			ping_slot_period,
			service_profile_id,
			routing_profile_id
		) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,
		mg.ID,
		mg.CreatedAt,
		mg.UpdatedAt,
		mg.MCAddr[:],
		mg.MCNwkSKey[:],
		mg.FCnt,
		mg.GroupType,
		mg.DR,
		mg.Frequency,
		mg.PingSlotPeriod,
		mg.ServiceProfileID,
		mg.RoutingProfileID,
	)
	if err != nil {
		return handlePSQLError(err, "insert error")
	}
	log.WithFields(log.Fields{
		"id":     mg.ID,
		"ctx_id": ctx.Value(logging.ContextIDKey),
	}).Info("multicast-group created")
	return nil
}
func GetMulticastGroup(ctx context.Context, db sqlx.Queryer, id uuid.UUID, forUpdate bool) (MulticastGroup, error) {
	var mg MulticastGroup
	var fu string
	if forUpdate {
		fu = " for update"
	}
	err := sqlx.Get(db, &mg, `
		select
			*
		from
			multicast_group
		where
			id = $1`+fu,
		id,
	)
	if err != nil {
		return mg, handlePSQLError(err, "select error")
	}
	return mg, nil
}