diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index d5c9a1702..ec4a0e196 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -184,7 +184,7 @@ CREATE TABLE `tp_action_triggers` ( `direction` varchar(8) NOT NULL, `threshold_type` char(12) NOT NULL, `threshold_value` DECIMAL(20,4) NOT NULL, - `recurrent` bool NOT NULL, + `recurrent` BOOLEAN NOT NULL, `min_sleep` int(11) NOT NULL, `destination_tag` varchar(64) NOT NULL, `balance_weight` DECIMAL(8,2) NOT NULL, diff --git a/data/storage/postgres/create_tariffplan_tables.sql b/data/storage/postgres/create_tariffplan_tables.sql index c770fe196..a388415ad 100644 --- a/data/storage/postgres/create_tariffplan_tables.sql +++ b/data/storage/postgres/create_tariffplan_tables.sql @@ -161,7 +161,7 @@ CREATE TABLE tp_action_triggers ( direction VARCHAR(8) NOT NULL, threshold_type char(12) NOT NULL, threshold_value NUMERIC(20,4) NOT NULL, - recurrent bool NOT NULL, + recurrent BOOLEAN NOT NULL, min_sleep INTEGER NOT NULL, destination_tag VARCHAR(64) NOT NULL, balance_weight NUMERIC(8,2) NOT NULL, diff --git a/data/storage/postgres/setup_cgr_db.sh b/data/storage/postgres/setup_cgr_db.sh index ad1d7324a..79018cc25 100755 --- a/data/storage/postgres/setup_cgr_db.sh +++ b/data/storage/postgres/setup_cgr_db.sh @@ -1,6 +1,5 @@ #! /usr/bin/env sh -export PGPASSWORD="CGRateS.org" user=$1 if [ -z "$1" ]; then @@ -14,6 +13,8 @@ fi ./create_db_with_users.sh +export PGPASSWORD="CGRateS.org" + psql -U $user -h $host -d cgrates -f create_cdrs_tables.sql cdrt=$? psql -U $user -h $host -d cgrates -f create_tariffplan_tables.sql diff --git a/engine/loader_csv.go b/engine/loader_csv.go index 25bf54319..b87c3500a 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -407,7 +407,7 @@ func (csvr *CSVReader) LoadRates() (err error) { if exists { rss := existingRates.RateSlots if err := ValidNextGroup(rss[len(rss)-1], r.RateSlots[0]); err != nil { - return err + return fmt.Errorf("RatesTag: %s, error: <%s>", tag, err.Error()) } csvr.rates[tag].RateSlots = append(csvr.rates[tag].RateSlots, r.RateSlots[0]) } else { diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index 570298a74..34df2629d 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -114,7 +114,7 @@ func NewLoadRate(tag, connectFee, price, ratedUnits, rateIncrements, groupInterv func ValidNextGroup(present, next *utils.RateSlot) error { if next.GroupIntervalStartDuration() <= present.GroupIntervalStartDuration() { - return errors.New(fmt.Sprintf("Next rate group interval start must be heigher than the last one: %#v", next)) + return errors.New(fmt.Sprintf("Next rate group interval start: %#v must be heigher than the previous one: %#v", next, present)) } if math.Mod(next.GroupIntervalStartDuration().Seconds(), present.RateIncrementDuration().Seconds()) != 0 { return errors.New(fmt.Sprintf("GroupIntervalStart of %#v must be a multiple of RateIncrement of %#v", next, present)) diff --git a/engine/models.go b/engine/models.go index 7576179b0..c743ac448 100644 --- a/engine/models.go +++ b/engine/models.go @@ -152,7 +152,7 @@ type TpActionTrigger struct { Direction string ThresholdType string ThresholdValue float64 - Recurrent int + Recurrent bool MinSleep int64 DestinationTag string BalanceWeight float64 diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 333d7d223..b81952c7f 100644 --- a/engine/storage_mysql.go +++ b/engine/storage_mysql.go @@ -63,3 +63,14 @@ func (self *MySQLStorage) Flush() (err error) { } return nil } + +func (self *MySQLStorage) SetTPTiming(tm *utils.ApierTPTiming) error { + if tm == nil { + return nil //Nothing to set + } + if _, err := self.Db.Exec(fmt.Sprintf("INSERT INTO %s (tpid, tag, years, months, month_days, week_days, time) VALUES('%s','%s','%s','%s','%s','%s','%s') ON DUPLICATE KEY UPDATE years=values(years), months=values(months), month_days=values(month_days), week_days=values(week_days), time=values(time)", + utils.TBL_TP_TIMINGS, tm.TPid, tm.TimingId, tm.Years, tm.Months, tm.MonthDays, tm.WeekDays, tm.Time)); err != nil { + return err + } + return nil +} diff --git a/engine/storage_mysql_local_test.go b/engine/storage_mysql_local_test.go index 5140e6a14..d2dea9c59 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -56,7 +56,255 @@ func TestMySQLCreateTables(t *testing.T) { } } -func TestRemoveData(t *testing.T) { +func TestMySQLSetGetTPTiming(t *testing.T) { + if !*testLocal { + return + } + tm := &utils.ApierTPTiming{TPid: TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"} + if err := mysqlDb.SetTPTiming(tm); err != nil { + t.Error(err.Error()) + } + if tmgs, err := mysqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) { + t.Errorf("Expecting: %+v, received: %+v", tm, tmgs[tm.TimingId]) + } +} + +func TestMySQLSetGetTPDestination(t *testing.T) { + if !*testLocal { + return + } + dst := &Destination{Id: TEST_SQL, Prefixes: []string{"+49", "+49151", "+49176"}} + if err := mysqlDb.SetTPDestination(TEST_SQL, dst); err != nil { + t.Error(err.Error()) + } + if dsts, err := mysqlDb.GetTpDestinations(TEST_SQL, TEST_SQL); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(dst, dsts[TEST_SQL]) { + t.Errorf("Expecting: %+v, received: %+v", dst, dsts[TEST_SQL]) + } +} + +func TestMySQLSetGetTPRates(t *testing.T) { + if !*testLocal { + return + } + RT_ID := "RT_1" + rtSlots := []*utils.RateSlot{ + &utils.RateSlot{ConnectFee: 0.02, Rate: 0.01, RateUnit: "60s", RateIncrement: "60s", GroupIntervalStart: "0s"}, + &utils.RateSlot{ConnectFee: 0.00, Rate: 0.005, RateUnit: "60s", RateIncrement: "1s", GroupIntervalStart: "60s"}, + } + for _, rs := range rtSlots { + rs.SetDurations() + } + mpRates := map[string][]*utils.RateSlot{RT_ID: rtSlots} + expectedTPRate := &utils.TPRate{TPid: TEST_SQL, RateId: RT_ID, RateSlots: rtSlots} + if err := mysqlDb.SetTPRates(TEST_SQL, mpRates); err != nil { + t.Error(err.Error()) + } + if rts, err := mysqlDb.GetTpRates(TEST_SQL, RT_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(expectedTPRate, rts[RT_ID]) { + t.Errorf("Expecting: %+v, received: %+v", expectedTPRate, rts[RT_ID]) + } +} + +func TestMySQLSetGetTPDestinationRates(t *testing.T) { + if !*testLocal { + return + } + DR_ID := "DR_1" + dr := &utils.DestinationRate{DestinationId: "DST_1", RateId: "RT_1", RoundingMethod: "*up", RoundingDecimals: 4} + drs := map[string][]*utils.DestinationRate{DR_ID: []*utils.DestinationRate{dr}} + eDrs := &utils.TPDestinationRate{TPid: TEST_SQL, DestinationRateId: DR_ID, DestinationRates: []*utils.DestinationRate{dr}} + if err := mysqlDb.SetTPDestinationRates(TEST_SQL, drs); err != nil { + t.Error(err.Error()) + } + if drs, err := mysqlDb.GetTpDestinationRates(TEST_SQL, DR_ID, nil); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(eDrs, drs[DR_ID]) { + fmt.Printf("Received: %+v\n", drs[DR_ID].DestinationRates[0]) + t.Errorf("Expecting: %+v, received: %+v", eDrs, drs[DR_ID]) + } +} + +func TestMySQLSetGetTPRatingPlans(t *testing.T) { + if !*testLocal { + return + } + RP_ID := "RP_1" + rbBinding := &utils.TPRatingPlanBinding{DestinationRatesId: "DR_1", TimingId: "TM_1", Weight: 10.0} + drts := map[string][]*utils.TPRatingPlanBinding{RP_ID: []*utils.TPRatingPlanBinding{rbBinding}} + if err := mysqlDb.SetTPRatingPlans(TEST_SQL, drts); err != nil { + t.Error(err.Error()) + } + if drps, err := mysqlDb.GetTpRatingPlans(TEST_SQL, RP_ID, nil); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(drts, drps) { + t.Errorf("Expecting: %+v, received: %+v", drts, drps) + } +} + +func TestMySQLSetGetTPRatingProfiles(t *testing.T) { + if !*testLocal { + return + } + ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RP_1"}} + rp := &utils.TPRatingProfile{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras} + setRps := map[string]*utils.TPRatingProfile{rp.KeyId(): rp} + if err := mysqlDb.SetTPRatingProfiles(TEST_SQL, setRps); err != nil { + t.Error(err.Error()) + } + if rps, err := mysqlDb.GetTpRatingProfiles(rp); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(setRps, rps) { + t.Errorf("Expecting: %+v, received: %+v", setRps, rps) + } + +} + +func TestMySQLSetGetTPSharedGroups(t *testing.T) { + if !*testLocal { + return + } + SG_ID := "SG_1" + setSgs := map[string][]*utils.TPSharedGroup{SG_ID: []*utils.TPSharedGroup{&utils.TPSharedGroup{Account: "dan", Strategy: "*lowest_first", RatingSubject: "lowest_rates"}}} + if err := mysqlDb.SetTPSharedGroups(TEST_SQL, setSgs); err != nil { + t.Error(err.Error()) + } + if sgs, err := mysqlDb.GetTpSharedGroups(TEST_SQL, SG_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(setSgs, sgs) { + t.Errorf("Expecting: %+v, received: %+v", setSgs, sgs) + } +} + +func TestMySQLSetGetTPCdrStats(t *testing.T) { + if !*testLocal { + return + } + CS_ID := "CDRSTATS_1" + setCS := map[string][]*utils.TPCdrStat{CS_ID: []*utils.TPCdrStat{ + &utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenant: "cgrates.org", Category: "call"}, + }} + if err := mysqlDb.SetTPCdrStats(TEST_SQL, setCS); err != nil { + t.Error(err.Error()) + } + if cs, err := mysqlDb.GetTpCdrStats(TEST_SQL, CS_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(setCS, cs) { + t.Errorf("Expecting: %+v, received: %+v", setCS, cs) + } +} + +func TestMySQLSetGetTPDerivedChargers(t *testing.T) { + if !*testLocal { + return + } + dc := &utils.TPDerivedCharger{RunId: utils.DEFAULT_RUNID, ReqTypeField: "^prepaid", AccountField: "^rif", SubjectField: "^rif", UsageField: "cgr_duration"} + dcs := &utils.TPDerivedChargers{TPid: TEST_SQL, Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: []*utils.TPDerivedCharger{dc}} + DCS_ID := dcs.GetDerivedChargesId() + setDCs := map[string][]*utils.TPDerivedCharger{DCS_ID: []*utils.TPDerivedCharger{dc}} + if err := mysqlDb.SetTPDerivedChargers(TEST_SQL, setDCs); err != nil { + t.Error(err.Error()) + } + if rDCs, err := mysqlDb.GetTpDerivedChargers(dcs); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(dcs, rDCs[DCS_ID]) { + t.Errorf("Expecting: %+v, received: %+v", dcs, rDCs[DCS_ID]) + } +} + +func TestMySQLSetGetTPActions(t *testing.T) { + if !*testLocal { + return + } + ACTS_ID := "PREPAID_10" + acts := []*utils.TPAction{ + &utils.TPAction{Identifier: "*topup_reset", BalanceType: "*monetary", Direction: "*out", Units: 10, ExpiryTime: "*unlimited", + DestinationId: "*any", BalanceWeight: 10, Weight: 10}} + tpActions := &utils.TPActions{TPid: TEST_SQL, ActionsId: ACTS_ID, Actions: acts} + if err := mysqlDb.SetTPActions(TEST_SQL, map[string][]*utils.TPAction{ACTS_ID: acts}); err != nil { + t.Error(err.Error()) + } + if rTpActs, err := mysqlDb.GetTPActions(TEST_SQL, ACTS_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(tpActions, rTpActs) { + t.Errorf("Expecting: %+v, received: %+v", tpActions, rTpActs) + } +} + +func TestMySQLTPActionTimings(t *testing.T) { + if !*testLocal { + return + } + AP_ID := "AP_1" + ap := map[string][]*utils.TPActionTiming{AP_ID: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}}} + if err := mysqlDb.SetTPActionTimings(TEST_SQL, ap); err != nil { + t.Error(err.Error()) + } + if rAP, err := mysqlDb.GetTPActionTimings(TEST_SQL, AP_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(ap, rAP) { + t.Errorf("Expecting: %+v, received: %+v", ap, rAP) + } +} + +func TestMySQLSetGetTPActionTriggers(t *testing.T) { + if !*testLocal { + return + } + atrg := &utils.TPActionTrigger{ + BalanceType: "*monetary", + Direction: "*out", + ThresholdType: "*min_balance", + ThresholdValue: 2.0, + Recurrent: true, + DestinationId: "*any", + Weight: 10.0, + ActionsId: "LOG_BALANCE", + } + mpAtrgs := map[string][]*utils.TPActionTrigger{TEST_SQL: []*utils.TPActionTrigger{atrg}} + if err := mysqlDb.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } + if rcvMpAtrgs, err := mysqlDb.GetTpActionTriggers(TEST_SQL+"1", TEST_SQL); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if !reflect.DeepEqual(mpAtrgs, rcvMpAtrgs) { + t.Errorf("Expecting: %v, received: %v", mpAtrgs, rcvMpAtrgs) + } +} + +func TestMySQLSetGetTpAccountActions(t *testing.T) { + if !*testLocal { + return + } + aa := &utils.TPAccountActions{TPid: TEST_SQL, Tenant: "cgrates.org", Account: "1001", + Direction: "*out", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"} + if err := mysqlDb.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil { + t.Error(err.Error()) + } + if aas, err := mysqlDb.GetTpAccountActions(aa); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(aa, aas[aa.KeyId()]) { + t.Errorf("Expecting: %+v, received: %+v", aa, aas[aa.KeyId()]) + } +} + +func TestMySQLGetTPIds(t *testing.T) { + if !*testLocal { + return + } + eTPIds := []string{TEST_SQL} + if tpIds, err := mysqlDb.GetTPIds(); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(eTPIds, tpIds) { + t.Errorf("Expecting: %+v, received: %+v", eTPIds, tpIds) + } +} + +func TestMySQLRemoveTPData(t *testing.T) { if !*testLocal { return } @@ -99,7 +347,6 @@ func TestRemoveData(t *testing.T) { } else if err.Error() != "Record Not Found" { t.Error(err.Error()) } - // Create AccountActions aa := &utils.TPAccountActions{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Account: "1001", Direction: "*out", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"} @@ -169,7 +416,7 @@ func TestRemoveData(t *testing.T) { } } -func TestSetCdr(t *testing.T) { +func TestMySQLSetCdr(t *testing.T) { if !*testLocal { return } @@ -223,7 +470,7 @@ func TestSetCdr(t *testing.T) { } } -func TestSetRatedCdr(t *testing.T) { +func TestMySQLSetRatedCdr(t *testing.T) { if !*testLocal { return } @@ -253,7 +500,7 @@ func TestSetRatedCdr(t *testing.T) { } } -func TestCallCost(t *testing.T) { +func TestMySQLCallCost(t *testing.T) { if !*testLocal { return } @@ -287,7 +534,7 @@ func TestCallCost(t *testing.T) { } } -func TestGetStoredCdrs(t *testing.T) { +func TestMySQLGetStoredCdrs(t *testing.T) { if !*testLocal { return } @@ -566,28 +813,3 @@ func TestRemStoredCdrs(t *testing.T) { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } } - -func TestSetGetTPActionTriggers(t *testing.T) { - if !*testLocal { - return - } - atrg := &utils.TPActionTrigger{ - BalanceType: "*monetary", - Direction: "*out", - ThresholdType: "*min_balance", - ThresholdValue: 2.0, - Recurrent: true, - DestinationId: "*any", - Weight: 10.0, - ActionsId: "LOG_BALANCE", - } - mpAtrgs := map[string][]*utils.TPActionTrigger{TEST_SQL: []*utils.TPActionTrigger{atrg}} - if err := mysqlDb.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil { - t.Error("Unexpected error: ", err.Error()) - } - if rcvMpAtrgs, err := mysqlDb.GetTpActionTriggers(TEST_SQL+"1", TEST_SQL); err != nil { - t.Error("Unexpected error: ", err.Error()) - } else if !reflect.DeepEqual(mpAtrgs, rcvMpAtrgs) { - t.Errorf("Expecting: %v, received: %v", mpAtrgs, rcvMpAtrgs) - } -} diff --git a/engine/storage_postgres.go b/engine/storage_postgres.go index 685230124..d68438f4f 100644 --- a/engine/storage_postgres.go +++ b/engine/storage_postgres.go @@ -63,3 +63,20 @@ func (self *PostgresStorage) Flush() (err error) { } return nil } + +func (self *PostgresStorage) SetTPTiming(tm *utils.ApierTPTiming) error { + if tm == nil { + return nil //Nothing to set + } + tx := self.db.Begin() + if err := tx.Where(&TpTiming{Tpid: tm.TPid, Tag: tm.TimingId}).Delete(TpTiming{}).Error; err != nil { + tx.Rollback() + return err + } + if err := tx.Save(&TpTiming{Tpid: tm.TPid, Tag: tm.TimingId, Years: tm.Years, Months: tm.Months, MonthDays: tm.MonthDays, WeekDays: tm.WeekDays, Time: tm.Time}).Error; err != nil { + tx.Rollback() + return err + } + tx.Commit() + return nil +} diff --git a/engine/storage_psql_local_test.go b/engine/storage_psql_local_test.go index f405c14e7..6e5084591 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -21,9 +21,9 @@ package engine import ( "fmt" "path" - //"reflect" + "reflect" "testing" - //"time" + "time" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" @@ -55,3 +55,768 @@ func TestPSQLCreateTables(t *testing.T) { } } } + +func TestPSQLSetGetTPTiming(t *testing.T) { + if !*testLocal { + return + } + tm := &utils.ApierTPTiming{TPid: TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"} + if err := psqlDb.SetTPTiming(tm); err != nil { + t.Error(err.Error()) + } + if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(tm, tmgs[tm.TimingId]) { + t.Errorf("Expecting: %+v, received: %+v", tmgs[tm.TimingId]) + } +} + +func TestPSQLSetGetTPDestination(t *testing.T) { + if !*testLocal { + return + } + dst := &Destination{Id: TEST_SQL, Prefixes: []string{"+49", "+49151", "+49176"}} + if err := psqlDb.SetTPDestination(TEST_SQL, dst); err != nil { + t.Error(err.Error()) + } + if dsts, err := psqlDb.GetTpDestinations(TEST_SQL, TEST_SQL); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(dst, dsts[TEST_SQL]) { + t.Errorf("Expecting: %+v, received: %+v", dst, dsts[TEST_SQL]) + } +} + +func TestPSQLSetGetTPRates(t *testing.T) { + if !*testLocal { + return + } + RT_ID := "RT_1" + rtSlots := []*utils.RateSlot{ + &utils.RateSlot{ConnectFee: 0.02, Rate: 0.01, RateUnit: "60s", RateIncrement: "60s", GroupIntervalStart: "0s"}, + &utils.RateSlot{ConnectFee: 0.00, Rate: 0.005, RateUnit: "60s", RateIncrement: "1s", GroupIntervalStart: "60s"}, + } + for _, rs := range rtSlots { + rs.SetDurations() + } + mpRates := map[string][]*utils.RateSlot{RT_ID: rtSlots} + expectedTPRate := &utils.TPRate{TPid: TEST_SQL, RateId: RT_ID, RateSlots: rtSlots} + if err := psqlDb.SetTPRates(TEST_SQL, mpRates); err != nil { + t.Error(err.Error()) + } + if rts, err := psqlDb.GetTpRates(TEST_SQL, RT_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(expectedTPRate, rts[RT_ID]) { + for _, slot := range rts[RT_ID].RateSlots { + fmt.Printf("Rates slot receievd: %+v\n", slot) + } + t.Errorf("Expecting: %+v, received: %+v", expectedTPRate, rts[RT_ID]) + } +} + +func TestPSQLSetGetTPDestinationRates(t *testing.T) { + if !*testLocal { + return + } + DR_ID := "DR_1" + dr := &utils.DestinationRate{DestinationId: "DST_1", RateId: "RT_1", RoundingMethod: "*up", RoundingDecimals: 4} + drs := map[string][]*utils.DestinationRate{DR_ID: []*utils.DestinationRate{dr}} + eDrs := &utils.TPDestinationRate{TPid: TEST_SQL, DestinationRateId: DR_ID, DestinationRates: []*utils.DestinationRate{dr}} + if err := psqlDb.SetTPDestinationRates(TEST_SQL, drs); err != nil { + t.Error(err.Error()) + } + if drs, err := psqlDb.GetTpDestinationRates(TEST_SQL, DR_ID, nil); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(eDrs, drs[DR_ID]) { + fmt.Printf("Received: %+v\n", drs[DR_ID].DestinationRates[0]) + t.Errorf("Expecting: %+v, received: %+v", eDrs, drs[DR_ID]) + } +} + +func TestPSQLSetGetTPRatingPlans(t *testing.T) { + if !*testLocal { + return + } + RP_ID := "RP_1" + rbBinding := &utils.TPRatingPlanBinding{DestinationRatesId: "DR_1", TimingId: "TM_1", Weight: 10.0} + drts := map[string][]*utils.TPRatingPlanBinding{RP_ID: []*utils.TPRatingPlanBinding{rbBinding}} + if err := psqlDb.SetTPRatingPlans(TEST_SQL, drts); err != nil { + t.Error(err.Error()) + } + if drps, err := psqlDb.GetTpRatingPlans(TEST_SQL, RP_ID, nil); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(drts, drps) { + t.Errorf("Expecting: %+v, received: %+v", drts, drps) + } +} + +func TestPSQLSetGetTPRatingProfiles(t *testing.T) { + if !*testLocal { + return + } + ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RP_1"}} + rp := &utils.TPRatingProfile{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras} + setRps := map[string]*utils.TPRatingProfile{rp.KeyId(): rp} + if err := psqlDb.SetTPRatingProfiles(TEST_SQL, setRps); err != nil { + t.Error(err.Error()) + } + if rps, err := psqlDb.GetTpRatingProfiles(rp); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(setRps, rps) { + t.Errorf("Expecting: %+v, received: %+v", setRps, rps) + } +} + +func TestPSQLSetGetTPSharedGroups(t *testing.T) { + if !*testLocal { + return + } + SG_ID := "SG_1" + setSgs := map[string][]*utils.TPSharedGroup{SG_ID: []*utils.TPSharedGroup{&utils.TPSharedGroup{Account: "dan", Strategy: "*lowest_first", RatingSubject: "lowest_rates"}}} + if err := psqlDb.SetTPSharedGroups(TEST_SQL, setSgs); err != nil { + t.Error(err.Error()) + } + if sgs, err := psqlDb.GetTpSharedGroups(TEST_SQL, SG_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(setSgs, sgs) { + t.Errorf("Expecting: %+v, received: %+v", setSgs, sgs) + } +} + +func TestPSQLSetGetTPCdrStats(t *testing.T) { + if !*testLocal { + return + } + CS_ID := "CDRSTATS_1" + setCS := map[string][]*utils.TPCdrStat{CS_ID: []*utils.TPCdrStat{ + &utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenant: "cgrates.org", Category: "call"}, + }} + if err := psqlDb.SetTPCdrStats(TEST_SQL, setCS); err != nil { + t.Error(err.Error()) + } + if cs, err := psqlDb.GetTpCdrStats(TEST_SQL, CS_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(setCS, cs) { + t.Errorf("Expecting: %+v, received: %+v", setCS, cs) + } +} + +func TestPSQLSetGetTPDerivedChargers(t *testing.T) { + if !*testLocal { + return + } + dc := &utils.TPDerivedCharger{RunId: utils.DEFAULT_RUNID, ReqTypeField: "^prepaid", AccountField: "^rif", SubjectField: "^rif", UsageField: "cgr_duration"} + dcs := &utils.TPDerivedChargers{TPid: TEST_SQL, Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "dan", Subject: "dan", DerivedChargers: []*utils.TPDerivedCharger{dc}} + DCS_ID := dcs.GetDerivedChargesId() + setDCs := map[string][]*utils.TPDerivedCharger{DCS_ID: []*utils.TPDerivedCharger{dc}} + if err := psqlDb.SetTPDerivedChargers(TEST_SQL, setDCs); err != nil { + t.Error(err.Error()) + } + if rDCs, err := psqlDb.GetTpDerivedChargers(dcs); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(dcs, rDCs[DCS_ID]) { + t.Errorf("Expecting: %+v, received: %+v", dcs, rDCs[DCS_ID]) + } +} + +func TestPSQLSetGetTPActions(t *testing.T) { + if !*testLocal { + return + } + ACTS_ID := "PREPAID_10" + acts := []*utils.TPAction{ + &utils.TPAction{Identifier: "*topup_reset", BalanceType: "*monetary", Direction: "*out", Units: 10, ExpiryTime: "*unlimited", + DestinationId: "*any", BalanceWeight: 10, Weight: 10}} + tpActions := &utils.TPActions{TPid: TEST_SQL, ActionsId: ACTS_ID, Actions: acts} + if err := psqlDb.SetTPActions(TEST_SQL, map[string][]*utils.TPAction{ACTS_ID: acts}); err != nil { + t.Error(err.Error()) + } + if rTpActs, err := psqlDb.GetTPActions(TEST_SQL, ACTS_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(tpActions, rTpActs) { + t.Errorf("Expecting: %+v, received: %+v", tpActions, rTpActs) + } +} + +func TestPSQLTPActionTimings(t *testing.T) { + if !*testLocal { + return + } + AP_ID := "AP_1" + ap := map[string][]*utils.TPActionTiming{AP_ID: []*utils.TPActionTiming{&utils.TPActionTiming{ActionsId: "ACTS_1", TimingId: "TM_1", Weight: 10.0}}} + if err := psqlDb.SetTPActionTimings(TEST_SQL, ap); err != nil { + t.Error(err.Error()) + } + if rAP, err := psqlDb.GetTPActionTimings(TEST_SQL, AP_ID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(ap, rAP) { + t.Errorf("Expecting: %+v, received: %+v", ap, rAP) + } +} + +func TestPSQLSetGetTPActionTriggers(t *testing.T) { + if !*testLocal { + return + } + atrg := &utils.TPActionTrigger{ + BalanceType: "*monetary", + Direction: "*out", + ThresholdType: "*min_balance", + ThresholdValue: 2.0, + Recurrent: true, + DestinationId: "*any", + Weight: 10.0, + ActionsId: "LOG_BALANCE", + } + mpAtrgs := map[string][]*utils.TPActionTrigger{TEST_SQL: []*utils.TPActionTrigger{atrg}} + if err := psqlDb.SetTPActionTriggers(TEST_SQL+"1", mpAtrgs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } + if rcvMpAtrgs, err := psqlDb.GetTpActionTriggers(TEST_SQL+"1", TEST_SQL); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if !reflect.DeepEqual(mpAtrgs, rcvMpAtrgs) { + t.Errorf("Expecting: %v, received: %v", mpAtrgs, rcvMpAtrgs) + } +} + +func TestPSQLSetGetTpAccountActions(t *testing.T) { + if !*testLocal { + return + } + aa := &utils.TPAccountActions{TPid: TEST_SQL, Tenant: "cgrates.org", Account: "1001", + Direction: "*out", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"} + if err := psqlDb.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil { + t.Error(err.Error()) + } + if aas, err := psqlDb.GetTpAccountActions(aa); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(aa, aas[aa.KeyId()]) { + t.Errorf("Expecting: %+v, received: %+v", aa, aas[aa.KeyId()]) + } +} + +func TestPSQLGetTPIds(t *testing.T) { + if !*testLocal { + return + } + eTPIds := []string{TEST_SQL} + if tpIds, err := psqlDb.GetTPIds(); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(eTPIds, tpIds) { + t.Errorf("Expecting: %+v, received: %+v", eTPIds, tpIds) + } +} + +func TestPSQLRemoveTPData(t *testing.T) { + if !*testLocal { + return + } + // Create Timings + tm := &utils.ApierTPTiming{TPid: TEST_SQL, TimingId: "ALWAYS", Time: "00:00:00"} + if err := psqlDb.SetTPTiming(tm); err != nil { + t.Error(err.Error()) + } + if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil { + t.Error(err.Error()) + } else if len(tmgs) == 0 { + t.Error("Could not store TPTiming") + } + // Remove Timings + if err := psqlDb.RemTPData(utils.TBL_TP_TIMINGS, TEST_SQL, tm.TimingId); err != nil { + t.Error(err.Error()) + } + if _, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err == nil { + t.Error("Should report error on querying here") + } else if err.Error() != "Record Not Found" { + t.Error(err.Error()) + } + // Create RatingProfile + ras := []*utils.TPRatingActivation{&utils.TPRatingActivation{ActivationTime: "2012-01-01T00:00:00Z", RatingPlanId: "RETAIL1"}} + rp := &utils.TPRatingProfile{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Category: "call", Direction: "*out", Subject: "*any", RatingPlanActivations: ras} + if err := psqlDb.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil { + t.Error(err.Error()) + } + if rps, err := psqlDb.GetTpRatingProfiles(rp); err != nil { + t.Error(err.Error()) + } else if len(rps) == 0 { + t.Error("Could not store TPRatingProfile") + } + // Remove RatingProfile + if err := psqlDb.RemTPData(utils.TBL_TP_RATE_PROFILES, rp.TPid, rp.LoadId, rp.Direction, rp.Tenant, rp.Category, rp.Subject); err != nil { + t.Error(err.Error()) + } + if _, err := psqlDb.GetTpRatingProfiles(rp); err == nil { + t.Error("Should return error in case of record not found from ORM") + } else if err.Error() != "Record Not Found" { + t.Error(err.Error()) + } + // Create AccountActions + aa := &utils.TPAccountActions{TPid: TEST_SQL, LoadId: TEST_SQL, Tenant: "cgrates.org", Account: "1001", + Direction: "*out", ActionPlanId: "PREPAID_10", ActionTriggersId: "STANDARD_TRIGGERS"} + if err := psqlDb.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil { + t.Error(err.Error()) + } + if aas, err := psqlDb.GetTpAccountActions(aa); err != nil { + t.Error(err.Error()) + } else if len(aas) == 0 { + t.Error("Could not create TPAccountActions") + } + // Remove AccountActions + if err := psqlDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.TPid, aa.LoadId, aa.Direction, aa.Tenant, aa.Account); err != nil { + t.Error(err.Error()) + } + if _, err := psqlDb.GetTpAccountActions(aa); err == nil { + t.Error("Should receive error in case of not found") + } else if err.Error() != "Record Not Found" { + t.Error(err.Error()) + } + // Create again so we can test complete TP removal + if err := psqlDb.SetTPTiming(tm); err != nil { + t.Error(err.Error()) + } + if tmgs, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err != nil { + t.Error(err.Error()) + } else if len(tmgs) == 0 { + t.Error("Could not store TPTiming") + } + // Create RatingProfile + if err := psqlDb.SetTPRatingProfiles(TEST_SQL, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil { + t.Error(err.Error()) + } + if rps, err := psqlDb.GetTpRatingProfiles(rp); err != nil { + t.Error(err.Error()) + } else if len(rps) == 0 { + t.Error("Could not store TPRatingProfile") + } + // Create AccountActions + if err := psqlDb.SetTPAccountActions(aa.TPid, map[string]*utils.TPAccountActions{aa.KeyId(): aa}); err != nil { + t.Error(err.Error()) + } + if aas, err := psqlDb.GetTpAccountActions(aa); err != nil { + t.Error(err.Error()) + } else if len(aas) == 0 { + t.Error("Could not create TPAccountActions") + } + // Remove TariffPlan completely + if err := psqlDb.RemTPData("", TEST_SQL); err != nil { + t.Error(err.Error()) + } + // Make sure we have removed it + if _, err := psqlDb.GetTpTimings(TEST_SQL, tm.TimingId); err == nil { + t.Error("Should report error on querying here") + } else if err.Error() != "Record Not Found" { + t.Error(err.Error()) + } + if _, err := psqlDb.GetTpRatingProfiles(rp); err == nil { + t.Error("Should return error in case of record not found from ORM") + } else if err.Error() != "Record Not Found" { + t.Error(err.Error()) + } + if _, err := psqlDb.GetTpAccountActions(aa); err == nil { + t.Error("Should receive error in case of not found") + } else if err.Error() != "Record Not Found" { + t.Error(err.Error()) + } +} + +func TestPSQLSetCdr(t *testing.T) { + if !*testLocal { + return + } + cgrCdr1 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa1", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "rated", utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:20Z", + utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "10s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", utils.CDRSOURCE: TEST_SQL} + cgrCdr2 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa2", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "prepaid", utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "1002", utils.SETUP_TIME: "2013-11-08T08:42:22Z", + utils.ANSWER_TIME: "2013-11-08T08:42:26Z", utils.USAGE: "20", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} + + cgrCdr3 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa3", utils.CDRHOST: "192.168.1.1", utils.REQTYPE: "rated", utils.DIRECTION: "*out", utils.TENANT: "cgrates.org", + utils.CATEGORY: "premium_call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "1001", utils.SETUP_TIME: "2013-11-07T08:42:24Z", + utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "60s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} + + cgrCdr4 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa4", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: "pseudoprepaid", utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", + utils.CATEGORY: "call", utils.ACCOUNT: "1001", utils.SUBJECT: "1001", utils.DESTINATION: "+4986517174964", utils.SETUP_TIME: "2013-11-07T08:42:21Z", + utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "1m2s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} + + cgrCdr5 := &utils.CgrCdr{utils.TOR: utils.VOICE, utils.ACCID: "aaa5", utils.CDRHOST: "192.168.1.2", utils.REQTYPE: "postpaid", utils.DIRECTION: "*out", utils.TENANT: "itsyscom.com", + utils.CATEGORY: "call", utils.ACCOUNT: "1002", utils.SUBJECT: "1002", utils.DESTINATION: "+4986517174963", utils.SETUP_TIME: "2013-11-07T08:42:25Z", + utils.ANSWER_TIME: "2013-11-07T08:42:26Z", utils.USAGE: "15s", "field_extr1": "val_extr1", "fieldextr2": "valextr2", "cdrsource": TEST_SQL} + + for _, cdr := range []*utils.CgrCdr{cgrCdr1, cgrCdr2, cgrCdr3, cgrCdr4, cgrCdr5} { + if err := psqlDb.SetCdr(cdr.AsStoredCdr()); err != nil { + t.Error(err.Error()) + } + } + strCdr1 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: "rated", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} + strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) + strCdr2 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN2", ReqType: "prepaid", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} + strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) + strCdr3 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: "rated", + Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1000", Destination: "+4986517174963", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} + strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String()) + + for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} { + if err := psqlDb.SetCdr(cdr); err != nil { + t.Error(err.Error()) + } + } +} + +/* +func TestPSQLSetRatedCdr(t *testing.T) { + if !*testLocal { + return + } + strCdr1 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb1", CdrHost: "192.168.1.1", CdrSource: "UNKNOWN", ReqType: "rated", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + MediationRunId: utils.DEFAULT_RUNID, Cost: 1.201} + strCdr1.CgrId = utils.Sha1(strCdr1.AccId, strCdr1.SetupTime.String()) + strCdr2 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb2", CdrHost: "192.168.1.2", CdrSource: "UNKNOWN", ReqType: "prepaid", + Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(12) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + MediationRunId: utils.DEFAULT_RUNID, Cost: 0.201} + strCdr2.CgrId = utils.Sha1(strCdr2.AccId, strCdr2.SetupTime.String()) + strCdr3 := &utils.StoredCdr{TOR: utils.VOICE, AccId: "bbb3", CdrHost: "192.168.1.1", CdrSource: TEST_SQL, ReqType: "rated", + Direction: "*out", Tenant: "itsyscom.com", Category: "call", Account: "1002", Subject: "1002", Destination: "+4986517174964", + SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), + Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, + MediationRunId: "wholesale_run", Cost: 1.201} + strCdr3.CgrId = utils.Sha1(strCdr3.AccId, strCdr3.SetupTime.String()) + + for _, cdr := range []*utils.StoredCdr{strCdr1, strCdr2, strCdr3} { + if err := psqlDb.SetRatedCdr(cdr, ""); err != nil { + t.Error(err.Error()) + } + } +} + + +func TestPSQLCallCost(t *testing.T) { + if !*testLocal { + return + } + cgrId := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()) + cc := &CallCost{ + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "91001", + Account: "8001", + Destination: "1002", + TOR: utils.VOICE, + Timespans: []*TimeSpan{ + &TimeSpan{ + TimeStart: time.Date(2013, 9, 10, 13, 40, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC), + }, + &TimeSpan{ + TimeStart: time.Date(2013, 9, 10, 13, 41, 0, 0, time.UTC), + TimeEnd: time.Date(2013, 9, 10, 13, 41, 30, 0, time.UTC), + }, + }, + } + if err := psqlDb.LogCallCost(cgrId, TEST_SQL, utils.DEFAULT_RUNID, cc); err != nil { + t.Error(err.Error()) + } + if ccRcv, err := psqlDb.GetCallCostLog(cgrId, TEST_SQL, utils.DEFAULT_RUNID); err != nil { + t.Error(err.Error()) + } else if !reflect.DeepEqual(cc, ccRcv) { + t.Errorf("Expecting call cost: %v, received: %v", cc, ccRcv) + } +} + + +func TestPSQLGetStoredCdrs(t *testing.T) { + if !*testLocal { + return + } + var timeStart, timeEnd time.Time + // All CDRs, no filter + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on cgrids + if storedCdrs, err := psqlDb.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 2 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on cgrids plus reqType + if storedCdrs, err := psqlDb.GetStoredCdrs([]string{utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()), + utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())}, + nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on runId + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, []string{utils.DEFAULT_RUNID}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 2 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on TOR + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, []string{utils.SMS}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 0 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple TOR + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, []string{utils.SMS, utils.VOICE}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on cdrHost + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.2"}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 3 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple cdrHost + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, []string{"192.168.1.1", "192.168.1.2"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on cdrSource + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN"}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple cdrSource + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{"UNKNOWN", "UNKNOWN2"}, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 2 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on reqType + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid"}, + nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 2 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple reqType + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"prepaid", "pseudoprepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, + 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 3 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on direction + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"*out"}, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on tenant + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 3 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple tenants + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com", "cgrates.org"}, nil, nil, nil, nil, nil, nil, + 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on tor + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call"}, + nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple tor + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call", "call"}, + nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on account + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1002"}, + nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 3 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple account + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "1002"}, + nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on subject + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000"}, + nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple subject + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000", "1002"}, + nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 3 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on destPrefix + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, []string{"+498651"}, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 3 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on multiple destPrefixes + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "+498651"}, nil, nil, + 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 4 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on ratedAccount + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, []string{"8001"}, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on ratedSubject + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, []string{"91001"}, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on ignoreErr + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, true, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on ignoreRated + var orderIdStart, orderIdEnd int64 // Capture also orderIds for the next test + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, true, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 5 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } else { + for _, cdr := range storedCdrs { + if cdr.OrderId < orderIdStart { + orderIdStart = cdr.OrderId + } + if cdr.OrderId > orderIdEnd { + orderIdEnd = cdr.OrderId + } + } + } + // Filter on orderIdStart + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 8 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on orderIdStart and orderIdEnd + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, orderIdStart, orderIdEnd+1, timeStart, timeEnd, + false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 5 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on timeStart + timeStart = time.Date(2013, 11, 8, 8, 0, 0, 0, time.UTC) + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 5 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on timeStart and timeEnd + timeEnd = time.Date(2013, 12, 1, 8, 0, 0, 0, time.UTC) + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 2 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Combined filter + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, []string{"rated"}, nil, nil, nil, nil, nil, + nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 1 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + // Filter on ignoreDerived + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, true, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 2 { // ToDo: Recheck this value + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } +} + +func TestRemStoredCdrs(t *testing.T) { + if !*testLocal { + return + } + var timeStart, timeEnd time.Time + cgrIdB1 := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()) + if err := psqlDb.RemStoredCdrs([]string{cgrIdB1}); err != nil { + t.Error(err.Error()) + } + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 7 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } + tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z") + cgrIdA1 := utils.Sha1("aaa1", tm.String()) + tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z") + cgrIdA2 := utils.Sha1("aaa2", tm.String()) + tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z") + cgrIdA3 := utils.Sha1("aaa3", tm.String()) + tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z") + cgrIdA4 := utils.Sha1("aaa4", tm.String()) + tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z") + cgrIdA5 := utils.Sha1("aaa5", tm.String()) + cgrIdB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()) + cgrIdB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()) + if err := psqlDb.RemStoredCdrs([]string{cgrIdA1, cgrIdA2, cgrIdA3, cgrIdA4, cgrIdA5, + cgrIdB2, cgrIdB3}); err != nil { + t.Error(err.Error()) + } + if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + t.Error(err.Error()) + } else if len(storedCdrs) != 0 { + t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) + } +} + +*/ diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 890ef3417..72113863d 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -101,6 +101,7 @@ func (self *SQLStorage) GetTPIds() ([]string, error) { return ids, nil } +// ToDo: PSQL TEST func (self *SQLStorage) GetTPTableIds(tpid, table string, distinct utils.TPDistinctIds, filters map[string]string, pagination *utils.Paginator) ([]string, error) { qry := fmt.Sprintf("SELECT DISTINCT %s FROM %s where tpid='%s'", distinct, table, tpid) @@ -156,15 +157,7 @@ func (self *SQLStorage) GetTPTableIds(tpid, table string, distinct utils.TPDisti } func (self *SQLStorage) SetTPTiming(tm *utils.ApierTPTiming) error { - if tm == nil { - return nil //Nothing to set - } - if _, err := self.Db.Exec(fmt.Sprintf("INSERT INTO %s (tpid, tag, years, months, month_days, week_days, time) VALUES('%s','%s','%s','%s','%s','%s','%s') ON DUPLICATE KEY UPDATE years=values(years), months=values(months), month_days=values(month_days), week_days=values(week_days), time=values(time)", - utils.TBL_TP_TIMINGS, tm.TPid, tm.TimingId, tm.Years, tm.Months, tm.MonthDays, tm.WeekDays, tm.Time)); err != nil { - - return err - } - return nil + return errors.New(utils.ERR_NOT_IMPLEMENTED) } func (self *SQLStorage) RemTPData(table, tpid string, args ...string) error { @@ -205,16 +198,19 @@ func (self *SQLStorage) SetTPDestination(tpid string, dest *Destination) error { return nil } tx := self.db.Begin() - tx.Where("tpid = ?", tpid).Where("tag = ?", dest.Id).Delete(TpDestination{}) + if err := tx.Where(&TpDestination{Tpid: tpid, Tag: dest.Id}).Delete(TpDestination{}).Error; err != nil { + tx.Rollback() + return err + } for _, prefix := range dest.Prefixes { - db := tx.Save(TpDestination{ + save := tx.Save(TpDestination{ Tpid: tpid, Tag: dest.Id, Prefix: prefix, }) - if db.Error != nil { + if save.Error != nil { tx.Rollback() - return db.Error + return save.Error } } tx.Commit() @@ -227,9 +223,12 @@ func (self *SQLStorage) SetTPRates(tpid string, rts map[string][]*utils.RateSlot } tx := self.db.Begin() for rtId, rSlots := range rts { - tx.Where("tpid = ?", tpid).Where("tag = ?", rtId).Delete(TpRate{}) + if err := tx.Where(&TpRate{Tpid: tpid, Tag: rtId}).Delete(TpRate{}).Error; err != nil { + tx.Rollback() + return err + } for _, rs := range rSlots { - tx.Save(TpRate{ + save := tx.Save(TpRate{ Tpid: tpid, Tag: rtId, ConnectFee: rs.ConnectFee, @@ -238,6 +237,11 @@ func (self *SQLStorage) SetTPRates(tpid string, rts map[string][]*utils.RateSlot RateIncrement: rs.RateIncrement, GroupIntervalStart: rs.GroupIntervalStart, }) + if save.Error != nil { + tx.Rollback() + return save.Error + } + } } tx.Commit() @@ -251,9 +255,12 @@ func (self *SQLStorage) SetTPDestinationRates(tpid string, drs map[string][]*uti tx := self.db.Begin() for drId, dRates := range drs { - tx.Where("tpid = ?", tpid).Where("tag = ?", drId).Delete(TpDestinationRate{}) + if err := tx.Where(&TpDestinationRate{Tpid: tpid, Tag: drId}).Delete(TpDestinationRate{}).Error; err != nil { + tx.Rollback() + return err + } for _, dr := range dRates { - tx.Save(TpDestinationRate{ + saved := tx.Save(TpDestinationRate{ Tpid: tpid, Tag: drId, DestinationsTag: dr.DestinationId, @@ -261,6 +268,10 @@ func (self *SQLStorage) SetTPDestinationRates(tpid string, drs map[string][]*uti RoundingMethod: dr.RoundingMethod, RoundingDecimals: dr.RoundingDecimals, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -273,15 +284,22 @@ func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string][]*utils.T } tx := self.db.Begin() for rpId, rPlans := range drts { - tx.Where("tpid = ?", tpid).Where("tag = ?", rpId).Delete(TpRatingPlan{}) + if err := tx.Where(&TpRatingPlan{Tpid: tpid, Tag: rpId}).Delete(TpRatingPlan{}).Error; err != nil { + tx.Rollback() + return err + } for _, rp := range rPlans { - tx.Save(TpRatingPlan{ + saved := tx.Save(TpRatingPlan{ Tpid: tpid, Tag: rpId, DestratesTag: rp.DestinationRatesId, TimingTag: rp.TimingId, Weight: rp.Weight, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -294,16 +312,12 @@ func (self *SQLStorage) SetTPRatingProfiles(tpid string, rpfs map[string]*utils. } tx := self.db.Begin() for _, rpf := range rpfs { - // parse identifiers - tx.Where("tpid = ?", tpid). - Where("direction = ?", rpf.Direction). - Where("tenant = ?", rpf.Tenant). - Where("subject = ?", rpf.Subject). - Where("category = ?", rpf.Category). - Where("loadid = ?", rpf.LoadId). - Delete(TpRatingProfile{}) + if err := tx.Where(&TpRatingProfile{Tpid: tpid, Loadid: rpf.LoadId, Direction: rpf.Direction, Tenant: rpf.Tenant, Category: rpf.Category, Subject: rpf.Subject}).Delete(TpRatingProfile{}).Error; err != nil { + tx.Rollback() + return err + } for _, ra := range rpf.RatingPlanActivations { - tx.Save(TpRatingProfile{ + saved := tx.Save(TpRatingProfile{ Tpid: rpf.TPid, Loadid: rpf.LoadId, Tenant: rpf.Tenant, @@ -314,6 +328,10 @@ func (self *SQLStorage) SetTPRatingProfiles(tpid string, rpfs map[string]*utils. RatingPlanTag: ra.RatingPlanId, FallbackSubjects: ra.FallbackSubjects, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -326,15 +344,22 @@ func (self *SQLStorage) SetTPSharedGroups(tpid string, sgs map[string][]*utils.T } tx := self.db.Begin() for sgId, sGroups := range sgs { - tx.Where("tpid = ?", tpid).Where("tag = ?", sgId).Delete(TpSharedGroup{}) + if err := tx.Where(&TpSharedGroup{Tpid: tpid, Tag: sgId}).Delete(TpSharedGroup{}).Error; err != nil { + tx.Rollback() + return err + } for _, sg := range sGroups { - tx.Save(TpSharedGroup{ + saved := tx.Save(TpSharedGroup{ Tpid: tpid, Tag: sgId, Account: sg.Account, Strategy: sg.Strategy, RatingSubject: sg.RatingSubject, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -347,10 +372,13 @@ func (self *SQLStorage) SetTPCdrStats(tpid string, css map[string][]*utils.TPCdr } tx := self.db.Begin() for csId, cStats := range css { - tx.Where("tpid = ?", tpid).Where("tag = ?", csId).Delete(TpCdrStat{}) + if err := tx.Where(&TpCdrStat{Tpid: tpid, Tag: csId}).Delete(TpCdrStat{}).Error; err != nil { + tx.Rollback() + return err + } for _, cs := range cStats { ql, _ := strconv.Atoi(cs.QueueLength) - tx.Save(TpCdrStat{ + saved := tx.Save(TpCdrStat{ Tpid: tpid, Tag: csId, QueueLength: ql, @@ -374,6 +402,10 @@ func (self *SQLStorage) SetTPCdrStats(tpid string, css map[string][]*utils.TPCdr CostInterval: cs.CostInterval, ActionTriggers: cs.ActionTriggers, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -386,20 +418,15 @@ func (self *SQLStorage) SetTPDerivedChargers(tpid string, sgs map[string][]*util } tx := self.db.Begin() for dcId, dChargers := range sgs { - // parse identifiers - tmpDc := TpDerivedCharger{} + tmpDc := &TpDerivedCharger{} if err := tmpDc.SetDerivedChargersId(dcId); err != nil { tx.Rollback() return err } - tx.Where("tpid = ?", tpid). - Where("direction = ?", tmpDc.Direction). - Where("tenant = ?", tmpDc.Tenant). - Where("account = ?", tmpDc.Account). - Where("category = ?", tmpDc.Category). - Where("subject = ?", tmpDc.Subject). - Where("loadid = ?", tmpDc.Loadid). - Delete(TpDerivedCharger{}) + if err := tx.Where(tmpDc).Delete(TpDerivedCharger{}).Error; err != nil { + tx.Rollback() + return err + } for _, dc := range dChargers { newDc := TpDerivedCharger{ Tpid: tpid, @@ -420,7 +447,10 @@ func (self *SQLStorage) SetTPDerivedChargers(tpid string, sgs map[string][]*util tx.Rollback() return err } - tx.Save(newDc) + if err := tx.Save(newDc).Error; err != nil { + tx.Rollback() + return err + } } } tx.Commit() @@ -459,9 +489,12 @@ func (self *SQLStorage) SetTPActions(tpid string, acts map[string][]*utils.TPAct tx := self.db.Begin() for acId, acs := range acts { - tx.Where("tpid = ?", tpid).Where("tag = ?", acId).Delete(TpAction{}) + if err := tx.Where(&TpAction{Tpid: tpid, Tag: acId}).Delete(TpAction{}).Error; err != nil { + tx.Rollback() + return err + } for _, ac := range acs { - tx.Save(TpAction{ + saved := tx.Save(TpAction{ Tpid: tpid, Tag: acId, Action: ac.Identifier, @@ -477,6 +510,10 @@ func (self *SQLStorage) SetTPActions(tpid string, acts map[string][]*utils.TPAct ExtraParameters: ac.ExtraParameters, Weight: ac.Weight, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -484,36 +521,25 @@ func (self *SQLStorage) SetTPActions(tpid string, acts map[string][]*utils.TPAct } func (self *SQLStorage) GetTPActions(tpid, actsId string) (*utils.TPActions, error) { - rows, err := self.Db.Query(fmt.Sprintf("SELECT action,balance_type,direction,units,expiry_time,destination_tag,rating_subject,category,shared_group,balance_weight,extra_parameters,weight FROM %s WHERE tpid='%s' AND tag='%s'", utils.TBL_TP_ACTIONS, tpid, actsId)) - if err != nil { + acts := &utils.TPActions{TPid: tpid, ActionsId: actsId} + var tpActions []*TpAction + if err := self.db.Where(&TpAction{Tpid: tpid, Tag: actsId}).Find(&tpActions).Error; err != nil { return nil, err } - defer rows.Close() - acts := &utils.TPActions{TPid: tpid, ActionsId: actsId} - i := 0 - for rows.Next() { - i++ //Keep here a reference so we know we got at least one result - var action, balanceId, dir, destId, rateSubject, category, sharedGroup, expTime, extraParameters string - var units, balanceWeight, weight float64 - if err = rows.Scan(&action, &balanceId, &dir, &units, &expTime, &destId, &rateSubject, &category, &sharedGroup, &balanceWeight, &extraParameters, &weight); err != nil { - return nil, err - } + for _, tpAct := range tpActions { acts.Actions = append(acts.Actions, &utils.TPAction{ - Identifier: action, - BalanceType: balanceId, - Direction: dir, - Units: units, - ExpiryTime: expTime, - DestinationId: destId, - RatingSubject: rateSubject, - Category: category, - BalanceWeight: balanceWeight, - SharedGroup: sharedGroup, - ExtraParameters: extraParameters, - Weight: weight}) - } - if i == 0 { - return nil, nil + Identifier: tpAct.Action, + BalanceType: tpAct.BalanceType, + Direction: tpAct.Direction, + Units: tpAct.Units, + ExpiryTime: tpAct.ExpiryTime, + DestinationId: tpAct.DestinationTag, + RatingSubject: tpAct.RatingSubject, + Category: tpAct.Category, + BalanceWeight: tpAct.BalanceWeight, + SharedGroup: tpAct.SharedGroup, + ExtraParameters: tpAct.ExtraParameters, + Weight: tpAct.Weight}) } return acts, nil } @@ -525,15 +551,22 @@ func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string][]*utils. } tx := self.db.Begin() for apId, aPlans := range ats { - tx.Where("tpid = ?", tpid).Where("tag = ?", apId).Delete(TpActionPlan{}) + if err := tx.Where(&TpActionPlan{Tpid: tpid, Tag: apId}).Delete(TpActionPlan{}).Error; err != nil { + tx.Rollback() + return err + } for _, ap := range aPlans { - tx.Save(TpActionPlan{ + saved := tx.Save(TpActionPlan{ Tpid: tpid, Tag: apId, ActionsTag: ap.ActionsId, TimingTag: ap.TimingId, Weight: ap.Weight, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } r := tx.Commit() @@ -542,16 +575,10 @@ func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string][]*utils. func (self *SQLStorage) GetTPActionTimings(tpid, tag string) (map[string][]*utils.TPActionTiming, error) { ats := make(map[string][]*utils.TPActionTiming) - var tpActionPlans []TpActionPlan - q := self.db.Where("tpid = ?", tpid) - if len(tag) != 0 { - q = q.Where("tag = ?", tag) - } - if err := q.Find(&tpActionPlans).Error; err != nil { + if err := self.db.Where(&TpActionPlan{Tpid: tpid, Tag: tag}).Find(&tpActionPlans).Error; err != nil { return nil, err } - for _, tpAp := range tpActionPlans { ats[tpAp.Tag] = append(ats[tpAp.Tag], &utils.TPActionTiming{ActionsId: tpAp.ActionsTag, TimingId: tpAp.TimingTag, Weight: tpAp.Weight}) } @@ -564,20 +591,19 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils } tx := self.db.Begin() for atId, aTriggers := range ats { - tx.Where("tpid = ?", tpid).Where("tag = ?", atId).Delete(TpActionTrigger{}) + if err := tx.Where(&TpActionTrigger{Tpid: tpid, Tag: atId}).Delete(TpActionTrigger{}).Error; err != nil { + tx.Rollback() + return err + } for _, at := range aTriggers { - recurrent := 0 - if at.Recurrent { - recurrent = 1 - } - tx.Save(TpActionTrigger{ + saved := tx.Save(TpActionTrigger{ Tpid: tpid, Tag: atId, BalanceType: at.BalanceType, Direction: at.Direction, ThresholdType: at.ThresholdType, ThresholdValue: at.ThresholdValue, - Recurrent: recurrent, + Recurrent: at.Recurrent, MinSleep: int64(at.MinSleep), DestinationTag: at.DestinationId, BalanceWeight: at.BalanceWeight, @@ -589,6 +615,10 @@ func (self *SQLStorage) SetTPActionTriggers(tpid string, ats map[string][]*utils ActionsTag: at.ActionsId, Weight: at.Weight, }) + if saved.Error != nil { + tx.Rollback() + return saved.Error + } } } tx.Commit() @@ -1530,22 +1560,16 @@ func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*utils.TPAc func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*utils.TPActionTrigger, error) { ats := make(map[string][]*utils.TPActionTrigger) var tpActionTriggers []TpActionTrigger - q := self.db.Where("tpid = ?", tpid) - if len(tag) != 0 { - q = q.Where("tag = ?", tag) - } - if err := q.Find(&tpActionTriggers).Error; err != nil { + if err := self.db.Where(&TpActionTrigger{Tpid: tpid, Tag: tag}).Find(&tpActionTriggers).Error; err != nil { return nil, err } - for _, tpAt := range tpActionTriggers { - recurrent := tpAt.Recurrent == 1 at := &utils.TPActionTrigger{ BalanceType: tpAt.BalanceType, Direction: tpAt.Direction, ThresholdType: tpAt.ThresholdType, ThresholdValue: tpAt.ThresholdValue, - Recurrent: recurrent, + Recurrent: tpAt.Recurrent, MinSleep: time.Duration(tpAt.MinSleep), DestinationId: tpAt.DestinationTag, BalanceWeight: tpAt.BalanceWeight,