112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
package chainwalletroutesdb
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/tech/sendico/pkg/db/repository"
|
|
ri "github.com/tech/sendico/pkg/db/repository/index"
|
|
"github.com/tech/sendico/pkg/db/template"
|
|
"github.com/tech/sendico/pkg/merrors"
|
|
"github.com/tech/sendico/pkg/mlogger"
|
|
"github.com/tech/sendico/pkg/model"
|
|
"github.com/tech/sendico/pkg/mservice"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type ChainWalletRoutesDB struct {
|
|
template.DBImp[*model.ChainWalletRoute]
|
|
}
|
|
|
|
func Create(logger mlogger.Logger, db *mongo.Database) (*ChainWalletRoutesDB, error) {
|
|
p := &ChainWalletRoutesDB{
|
|
DBImp: *template.Create[*model.ChainWalletRoute](logger, mservice.WalletRoutes, db),
|
|
}
|
|
|
|
if err := p.Repository.CreateIndex(&ri.Definition{
|
|
Name: "idx_org_wallet_unique",
|
|
Unique: true,
|
|
Keys: []ri.Key{
|
|
{Field: "organizationRef", Sort: ri.Asc},
|
|
{Field: "walletRef", Sort: ri.Asc},
|
|
},
|
|
}); err != nil {
|
|
p.Logger.Error("Failed to create unique organization/wallet route index", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
if err := p.Repository.CreateIndex(&ri.Definition{
|
|
Name: "idx_wallet_ref",
|
|
Keys: []ri.Key{
|
|
{Field: "walletRef", Sort: ri.Asc},
|
|
},
|
|
}); err != nil {
|
|
p.Logger.Error("Failed to create wallet route lookup index", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
return p, nil
|
|
}
|
|
|
|
func (db *ChainWalletRoutesDB) Get(ctx context.Context, organizationRef string, walletRef string) (*model.ChainWalletRoute, error) {
|
|
org := model.ChainWalletRoute{OrganizationRef: organizationRef, WalletRef: walletRef}
|
|
org.Normalize()
|
|
if org.OrganizationRef == "" || org.WalletRef == "" {
|
|
return nil, merrors.InvalidArgument("wallet route requires organizationRef and walletRef")
|
|
}
|
|
|
|
var route model.ChainWalletRoute
|
|
query := repository.Query().
|
|
Filter(repository.Field("organizationRef"), org.OrganizationRef).
|
|
Filter(repository.Field("walletRef"), org.WalletRef)
|
|
return &route, db.FindOne(ctx, query, &route)
|
|
}
|
|
|
|
func (db *ChainWalletRoutesDB) Upsert(ctx context.Context, route *model.ChainWalletRoute) error {
|
|
if route == nil {
|
|
return merrors.InvalidArgument("wallet route is nil")
|
|
}
|
|
route.Normalize()
|
|
if route.OrganizationRef == "" || route.WalletRef == "" {
|
|
return merrors.InvalidArgument("wallet route requires organizationRef and walletRef")
|
|
}
|
|
if route.Network == "" && route.GatewayID == "" {
|
|
return merrors.InvalidArgument("wallet route requires network or gatewayId")
|
|
}
|
|
|
|
existing, err := db.Get(ctx, route.OrganizationRef, route.WalletRef)
|
|
if err != nil {
|
|
if !errors.Is(err, merrors.ErrNoData) {
|
|
return err
|
|
}
|
|
if createErr := db.Create(ctx, route); createErr != nil {
|
|
if errors.Is(createErr, merrors.ErrDataConflict) {
|
|
existing, err = db.Get(ctx, route.OrganizationRef, route.WalletRef)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
return createErr
|
|
}
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
changed := false
|
|
if route.Network != "" && existing.Network != route.Network {
|
|
existing.Network = route.Network
|
|
changed = true
|
|
}
|
|
if route.GatewayID != "" && existing.GatewayID != route.GatewayID {
|
|
existing.GatewayID = route.GatewayID
|
|
changed = true
|
|
}
|
|
if !changed {
|
|
return nil
|
|
}
|
|
|
|
return db.Update(ctx, existing)
|
|
}
|