diff --git a/apier/tpdestinationrates.go b/apier/tpdestinationrates.go index 2878b2d66..e649cb8c5 100644 --- a/apier/tpdestinationrates.go +++ b/apier/tpdestinationrates.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/cgrates/engine" ) // Creates a new DestinationRate profile within a tariff plan @@ -36,7 +37,11 @@ func (self *Apier) SetTPDestinationRate(attrs utils.TPDestinationRate, reply *st } else if exists { return errors.New(utils.ERR_DUPLICATE) } - if err := self.StorDb.SetTPDestinationRate(&attrs); err != nil { + drs := make([]*engine.DestinationRate, len(attrs.DestinationRates)) + for idx,dr := range attrs.DestinationRates { + drs[idx] = &engine.DestinationRate{attrs.DestinationRateId, dr.DestinationId, dr.RateId, nil} + } + if err := self.StorDb.SetTPDestinationRates( attrs.TPid, map[string][]*engine.DestinationRate{ attrs.DestinationRateId: drs } ); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } *reply = "OK" diff --git a/engine/storage_interface.go b/engine/storage_interface.go index d3f8374c0..15ebaea40 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -72,7 +72,7 @@ type DataStorage interface { GetTPRate(string, string) (*utils.TPRate, error) GetTPRateIds(string) ([]string, error) ExistsTPDestinationRate(string, string) (bool, error) - SetTPDestinationRate(*utils.TPDestinationRate) error + SetTPDestinationRates(string, map[string][]*DestinationRate) error GetTPDestinationRate(string, string) (*utils.TPDestinationRate, error) GetTPDestinationRateIds(string) ([]string, error) ExistsTPDestRateTiming(string, string) (bool, error) diff --git a/engine/storage_map.go b/engine/storage_map.go index 78cdf78e6..6be87a9ea 100644 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -129,7 +129,7 @@ func (ms *MapStorage) ExistsTPDestinationRate(tpid, drId string) (bool, error) { return false, errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (ms *MapStorage) SetTPDestinationRate(dr *utils.TPDestinationRate) error { +func (ms *MapStorage) SetTPDestinationRates(tpid string, drs map[string][]*DestinationRate) error { return errors.New(utils.ERR_NOT_IMPLEMENTED) } diff --git a/engine/storage_mongo.go b/engine/storage_mongo.go index c6bf13c8b..9c86f6b7a 100644 --- a/engine/storage_mongo.go +++ b/engine/storage_mongo.go @@ -204,7 +204,7 @@ func (ms *MongoStorage) ExistsTPDestinationRate(tpid, drId string) (bool, error) return false, errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (ms *MongoStorage) SetTPDestinationRate(dr *utils.TPDestinationRate) error { +func (ms *MongoStorage) SetTPDestinationRates(tpid string, drs map[string][]*DestinationRate) error { return errors.New(utils.ERR_NOT_IMPLEMENTED) } diff --git a/engine/storage_redis.go b/engine/storage_redis.go index 9725764a5..ea2d2895a 100644 --- a/engine/storage_redis.go +++ b/engine/storage_redis.go @@ -159,7 +159,7 @@ func (rs *RedisStorage) ExistsTPDestinationRate(tpid, drId string) (bool, error) return false, errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (rs *RedisStorage) SetTPDestinationRate(dr *utils.TPDestinationRate) error { +func (rs *RedisStorage) SetTPDestinationRates(tpid string, drs map[string][]*DestinationRate) error { return errors.New(utils.ERR_NOT_IMPLEMENTED) } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 20c7458f4..64b336fe9 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -289,17 +289,19 @@ func (self *SQLStorage) ExistsTPDestinationRate(tpid, drId string) (bool, error) return exists, nil } -func (self *SQLStorage) SetTPDestinationRate(dr *utils.TPDestinationRate) error { - if len(dr.DestinationRates) == 0 { +func (self *SQLStorage) SetTPDestinationRates(tpid string, drs map[string][]*DestinationRate) error { + if len(drs) == 0 { return nil //Nothing to set } - // Using multiple values in query to spare some network processing time qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, destinations_tag, rates_tag) VALUES ", utils.TBL_TP_DESTINATION_RATES) - for idx, drPair := range dr.DestinationRates { - if idx != 0 { //Consecutive values after the first will be prefixed with "," as separator - qry += "," + for drId, drRows := range drs { + for idx, dr := range drRows { + if idx != 0 { //Consecutive values after the first will be prefixed with "," as separator + qry += "," + } + qry += fmt.Sprintf("('%s','%s','%s','%s')", + tpid, drId, dr.DestinationsTag, dr.RateTag) } - qry += fmt.Sprintf("('%s','%s','%s','%s')", dr.TPid, dr.DestinationRateId, drPair.DestinationId, drPair.RateId) } if _, err := self.Db.Exec(qry); err != nil { return err diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index b268ba347..f3f4d9102 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -150,7 +150,35 @@ func (self *TPCSVImporter) importRates(fn string) error { return nil } -func (self *TPCSVImporter) importDestinationRates(fPath string) error { +func (self *TPCSVImporter) importDestinationRates(fn string) error { + if self.Verbose { + log.Printf("Processing file: <%s> ", fn) + } + fParser, err := NewTPCSVFileParser( self.DirPath, fn ) + if err!=nil { + return err + } + lineNr := 0 + for { + lineNr++ + record, err := fParser.ParseNextLine() + if err == io.EOF { // Reached end of file + break + } else if err != nil { + if self.Verbose { + log.Printf("Ignoring line %d, warning: <%s> ", lineNr, err.Error()) + } + continue + } + dr := &DestinationRate{record[0], record[1], record[2], nil} + if err != nil { + return err + } + if err := self.StorDb.SetTPDestinationRates( self.TPid, + map[string][]*DestinationRate{ dr.Tag: []*DestinationRate{dr} } ); err != nil { + log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error()) + } + } return nil }