diff --git a/apier/v1/cdre.go b/apier/v1/cdre.go index d6967c287..ebc5da984 100644 --- a/apier/v1/cdre.go +++ b/apier/v1/cdre.go @@ -92,18 +92,7 @@ func (self *ApierV1) ExportCdrsToZipString(attr utils.AttrExpFileCdrs, reply *st // Export Cdrs to file func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.ExportedFileCdrs) error { - var tStart, tEnd time.Time var err error - if len(attr.TimeStart) != 0 { - if tStart, err = utils.ParseTimeDetectLayout(attr.TimeStart); err != nil { - return err - } - } - if len(attr.TimeEnd) != 0 { - if tEnd, err = utils.ParseTimeDetectLayout(attr.TimeEnd); err != nil { - return err - } - } exportTemplate := self.Config.CdreDefaultInstance if attr.ExportTemplate != nil && len(*attr.ExportTemplate) != 0 { // XML Template defined, can be field names or xml reference if strings.HasPrefix(*attr.ExportTemplate, utils.XML_PROFILE_PREFIX) { @@ -185,15 +174,11 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E if attr.MaskLength != nil { maskLen = *attr.MaskLength } - var costStart, costEnd *float64 - if attr.SkipRated { - costEnd = utils.Float64Pointer(0.0) - } else if attr.SkipErrors { - costEnd = utils.Float64Pointer(-1.0) + cdrsFltr, err := attr.AsCdrsFilter() + if err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } - cdrs, err := self.CdrDb.GetStoredCdrs(attr.CgrIds, nil, attr.MediationRunIds, nil, attr.TORs, nil, attr.CdrHosts, nil, attr.CdrSources, nil, attr.ReqTypes, nil, attr.Directions, nil, - attr.Tenants, nil, attr.Categories, nil, attr.Accounts, nil, attr.Subjects, nil, attr.DestinationPrefixes, nil, attr.RatedAccounts, nil, attr.RatedSubjects, nil, nil, nil, nil, nil, &attr.OrderIdStart, &attr.OrderIdEnd, - nil, nil, &tStart, &tEnd, nil, nil, nil, nil, costStart, costEnd, false, nil) + cdrs, err := self.CdrDb.GetStoredCdrs(cdrsFltr) if err != nil { return err } else if len(cdrs) == 0 { diff --git a/apier/v1/cdrs.go b/apier/v1/cdrs.go index c3a54a202..98b33c0ee 100644 --- a/apier/v1/cdrs.go +++ b/apier/v1/cdrs.go @@ -20,7 +20,6 @@ package v1 import ( "fmt" - "time" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" @@ -48,27 +47,11 @@ func (apier *ApierV1) GetCallCostLog(attrs AttrGetCallCost, reply *engine.CallCo // Retrieves CDRs based on the filters func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*utils.CgrCdrOut) error { - var tStart, tEnd time.Time - var err error - if len(attrs.TimeStart) != 0 { - if tStart, err = utils.ParseTimeDetectLayout(attrs.TimeStart); err != nil { - return err - } + cdrsFltr, err := attrs.AsCdrsFilter() + if err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } - if len(attrs.TimeEnd) != 0 { - if tEnd, err = utils.ParseTimeDetectLayout(attrs.TimeEnd); err != nil { - return err - } - } - var costStart, costEnd *float64 - if attrs.SkipRated { - costEnd = utils.Float64Pointer(0.0) - } else if attrs.SkipErrors { - costEnd = utils.Float64Pointer(-1.0) - } - if cdrs, err := apier.CdrDb.GetStoredCdrs(attrs.CgrIds, nil, attrs.MediationRunIds, nil, attrs.TORs, nil, attrs.CdrHosts, nil, attrs.CdrSources, nil, attrs.ReqTypes, nil, attrs.Directions, nil, - attrs.Tenants, nil, attrs.Categories, nil, attrs.Accounts, nil, attrs.Subjects, nil, attrs.DestinationPrefixes, nil, attrs.RatedAccounts, nil, attrs.RatedSubjects, nil, nil, nil, nil, nil, - &attrs.OrderIdStart, &attrs.OrderIdEnd, nil, nil, &tStart, &tEnd, nil, nil, nil, nil, costStart, costEnd, false, nil); err != nil { + if cdrs, err := apier.CdrDb.GetStoredCdrs(cdrsFltr); err != nil { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) } else if len(cdrs) == 0 { *reply = make([]*utils.CgrCdrOut, 0) diff --git a/engine/mediator.go b/engine/mediator.go index 54ea529bb..0bc18dc6b 100644 --- a/engine/mediator.go +++ b/engine/mediator.go @@ -196,9 +196,9 @@ func (self *Mediator) RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTy } else if rerateRated { costStart = utils.Float64Pointer(0.0) } - cdrs, err := self.cdrDb.GetStoredCdrs(cgrIds, nil, runIds, nil, tors, nil, cdrHosts, nil, cdrSources, nil, reqTypes, nil, directions, nil, - tenants, nil, categories, nil, accounts, nil, subjects, nil, destPrefixes, nil, ratedAccounts, nil, ratedSubjects, nil, - nil, nil, nil, nil, &orderIdStart, &orderIdEnd, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, costStart, costEnd, true, nil) + cdrs, err := self.cdrDb.GetStoredCdrs(&utils.CdrsFilter{CgrIds: cgrIds, RunIds: runIds, Tors: tors, CdrHosts: cdrHosts, CdrSources: cdrSources, ReqTypes: reqTypes, Directions: directions, + Tenants: tenants, Categories: categories, Accounts: accounts, Subjects: subjects, DestPrefixes: destPrefixes, RatedAccounts: ratedAccounts, RatedSubjects: ratedSubjects, + OrderIdStart: orderIdStart, OrderIdEnd: orderIdEnd, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd, CostStart: costStart, CostEnd: costEnd, IgnoreDerived: true}) if err != nil { return err } diff --git a/engine/mediator_local_test.go b/engine/mediator_local_test.go index cbbf1c7d6..aba4a2180 100644 --- a/engine/mediator_local_test.go +++ b/engine/mediator_local_test.go @@ -157,14 +157,12 @@ func TestMediPostCdrs(t *testing.T) { } } time.Sleep(100 * time.Millisecond) // Give time for CDRs to reach database - if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := cdrStor.GetStoredCdrs(new(utils.CdrsFilter)); err != nil { t.Error(err) } else if len(storedCdrs) != 6 { // Make sure CDRs made it into StorDb t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(storedCdrs))) } - if nonErrorCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(-1.0), false, nil); err != nil { + if nonErrorCdrs, err := cdrStor.GetStoredCdrs(&utils.CdrsFilter{CostEnd: utils.Float64Pointer(-1.0)}); err != nil { t.Error(err) } else if len(nonErrorCdrs) != 0 { t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(nonErrorCdrs))) @@ -187,14 +185,12 @@ func TestMediInjectCdrs(t *testing.T) { t.Error(err) } } - if storedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := cdrStor.GetStoredCdrs(new(utils.CdrsFilter)); err != nil { t.Error(err) } else if len(storedCdrs) != 8 { // Make sure CDRs made it into StorDb t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(storedCdrs))) } - if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(-1.0), false, nil); err != nil { + if nonRatedCdrs, err := cdrStor.GetStoredCdrs(&utils.CdrsFilter{CostEnd: utils.Float64Pointer(-1.0)}); err != nil { t.Error(err) } else if len(nonRatedCdrs) != 2 { // Just two of them should be non-rated t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs))) @@ -226,14 +222,12 @@ func TestMediRateCdrs(t *testing.T) { } else if reply != utils.OK { t.Errorf("Unexpected reply: %s", reply) } - if nonRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(-1.0), false, nil); err != nil { + if nonRatedCdrs, err := cdrStor.GetStoredCdrs(&utils.CdrsFilter{CostEnd: utils.Float64Pointer(-1.0)}); err != nil { t.Error(err) } else if len(nonRatedCdrs) != 2 { // All CDRs should be rated t.Error(fmt.Sprintf("Unexpected number of CDRs non-rated: %d", len(nonRatedCdrs))) } - if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(-1.0), utils.Float64Pointer(0), false, nil); err != nil { + if errRatedCdrs, err := cdrStor.GetStoredCdrs(&utils.CdrsFilter{CostStart: utils.Float64Pointer(-1.0), CostEnd: utils.Float64Pointer(0)}); err != nil { t.Error(err) } else if len(errRatedCdrs) != 2 { // The first 2 with errors should be still there before rerating t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs))) @@ -243,8 +237,7 @@ func TestMediRateCdrs(t *testing.T) { } else if reply != utils.OK { t.Errorf("Unexpected reply: %s", reply) } - if errRatedCdrs, err := cdrStor.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(-1.0), utils.Float64Pointer(0), false, nil); err != nil { + if errRatedCdrs, err := cdrStor.GetStoredCdrs(&utils.CdrsFilter{CostStart: utils.Float64Pointer(-1.0), CostEnd: utils.Float64Pointer(0)}); err != nil { t.Error(err) } else if len(errRatedCdrs) != 2 { t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs))) diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 0430dcd23..71a31615f 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -22,13 +22,11 @@ import ( "bytes" "encoding/gob" "encoding/json" + "reflect" "github.com/cgrates/cgrates/utils" "github.com/ugorji/go/codec" "labix.org/v2/mgo/bson" - - "reflect" - "time" ) const ( @@ -114,11 +112,7 @@ type CdrStorage interface { Storage SetCdr(*utils.StoredCdr) error SetRatedCdr(*utils.StoredCdr, string) error - GetStoredCdrs(cgrIds, notCgrIds, runIds, notRunIds, tors, notTors, cdrHosts, notCdrHosts, cdrSources, notCdrSources, reqTypes, notReqTypes, directions, notDirections, - tenants, notTenants, categories, notCategories, accounts, notAccounts, subjects, notSubjects, destContains, notDestContains, ratedAccounts, notRatedAccounts, ratedSubjects, notRatedSubjects []string, - costs []float64, notCosts []float64, extraFields map[string]string, notExtraFields map[string]string, - orderIdStart, orderIdEnd *int64, sTimeStart, sTimeEnd, aTimeStart, aTimeEnd *time.Time, usageStart, usageEnd, ratedUsageStart, ratedUsageEnd, costStart, costEnd *float64, ignoreDerived bool, - pagination *utils.Paginator) ([]*utils.StoredCdr, error) + GetStoredCdrs(*utils.CdrsFilter) ([]*utils.StoredCdr, error) RemStoredCdrs([]string) error } diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 31618cc89..0ed70a16a 100644 --- a/engine/storage_mysql.go +++ b/engine/storage_mysql.go @@ -41,7 +41,7 @@ func NewMySQLStorage(host, port, name, user, password string, maxConn, maxIdleCo } db.DB().SetMaxIdleConns(maxIdleConn) db.DB().SetMaxOpenConns(maxConn) - db.LogMode(true) + //db.LogMode(true) return &MySQLStorage{&SQLStorage{Db: db.DB(), db: db}}, nil } diff --git a/engine/storage_mysql_local_test.go b/engine/storage_mysql_local_test.go index 31892a15d..0cd2cc89c 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -560,210 +560,160 @@ func TestMySQLGetStoredCdrs(t *testing.T) { } var timeStart, timeEnd time.Time // All CDRs, no filter - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(new(utils.CdrsFilter)); 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 := mysqlDb.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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CgrIds: []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())}}); 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 := mysqlDb.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, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CgrIds: []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())}, ReqTypes: []string{"prepaid"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, []string{utils.DEFAULT_RUNID}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{RunIds: []string{utils.DEFAULT_RUNID}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{utils.SMS}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Tors: []string{utils.SMS}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, []string{utils.SMS, utils.VOICE}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Tors: []string{utils.SMS, utils.VOICE}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"192.168.1.2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrHosts: []string{"192.168.1.2"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, []string{"192.168.1.1", "192.168.1.2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrHosts: []string{"192.168.1.1", "192.168.1.2"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"UNKNOWN"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrSources: []string{"UNKNOWN"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, []string{"UNKNOWN", "UNKNOWN2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrSources: []string{"UNKNOWN", "UNKNOWN2"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"prepaid"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{ReqTypes: []string{"prepaid"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"prepaid", "pseudoprepaid"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{ReqTypes: []string{"prepaid", "pseudoprepaid"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"*out"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Directions: []string{"*out"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Tenants: []string{"itsyscom.com"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com", "cgrates.org"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Tenants: []string{"itsyscom.com", "cgrates.org"}}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 8 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } // Filter on category - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Categories: []string{"premium_call"}}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 1 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } - // Filter on multiple category - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call", "call"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + // Filter on multiple categories + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Categories: []string{"premium_call", "call"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1002"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Accounts: []string{"1002"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "1002"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Accounts: []string{"1001", "1002"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Subjects: []string{"1000"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000", "1002"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{Subjects: []string{"1000", "1002"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - []string{"+498651"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{DestPrefixes: []string{"+498651"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - []string{"1001", "+498651"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{DestPrefixes: []string{"1001", "+498651"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, []string{"8001"}, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{RatedAccounts: []string{"8001"}}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, []string{"91001"}, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{RatedSubjects: []string{"91001"}}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 1 { 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(0.0), false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{CostEnd: utils.Float64Pointer(0.0)}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 5 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -778,47 +728,39 @@ func TestMySQLGetStoredCdrs(t *testing.T) { } } // Filter on orderIdStart - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - &orderIdStart, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{OrderIdStart: orderIdStart}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - &orderIdStart, utils.Int64Pointer(orderIdEnd+1), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{OrderIdStart: orderIdStart, OrderIdEnd: orderIdEnd}); err != nil { t.Error(err.Error()) - } else if len(storedCdrs) != 5 { + } else if len(storedCdrs) != 4 { 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{AnswerTimeStart: &timeStart}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 2 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } // Combined filter - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"rated"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{ReqTypes: []string{"rated"}, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); 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 := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, nil, nil, true, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(&utils.CdrsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd, IgnoreDerived: true}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 0 { // ToDo: Recheck this value t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -833,8 +775,7 @@ func TestMySQLRemStoredCdrs(t *testing.T) { if err := mysqlDb.RemStoredCdrs([]string{cgrIdB1}); err != nil { t.Error(err.Error()) } - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(new(utils.CdrsFilter)); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 7 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -855,8 +796,7 @@ func TestMySQLRemStoredCdrs(t *testing.T) { cgrIdB2, cgrIdB3}); err != nil { t.Error(err.Error()) } - if storedCdrs, err := mysqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := mysqlDb.GetStoredCdrs(new(utils.CdrsFilter)); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 0 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) diff --git a/engine/storage_psql_local_test.go b/engine/storage_psql_local_test.go index e79fb2d18..0283c64bb 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -562,210 +562,160 @@ func TestPSQLGetStoredCdrs(t *testing.T) { } 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(new(utils.CdrsFilter)); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CgrIds: []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())}}); 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, nil, nil, nil, nil, nil, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CgrIds: []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())}, ReqTypes: []string{"prepaid"}}); 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, nil, []string{utils.DEFAULT_RUNID}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{RunIds: []string{utils.DEFAULT_RUNID}}); 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, nil, nil, []string{utils.SMS}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Tors: []string{utils.SMS}}); 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, nil, nil, []string{utils.SMS, utils.VOICE}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Tors: []string{utils.SMS, utils.VOICE}}); 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, nil, nil, nil, []string{"192.168.1.2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrHosts: []string{"192.168.1.2"}}); 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, nil, nil, nil, []string{"192.168.1.1", "192.168.1.2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrHosts: []string{"192.168.1.1", "192.168.1.2"}}); 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, nil, nil, nil, nil, []string{"UNKNOWN"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrSources: []string{"UNKNOWN"}}); 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, nil, nil, nil, nil, []string{"UNKNOWN", "UNKNOWN2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CdrSources: []string{"UNKNOWN", "UNKNOWN2"}}); 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, nil, nil, nil, nil, nil, []string{"prepaid"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{ReqTypes: []string{"prepaid"}}); 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, nil, nil, nil, nil, nil, []string{"prepaid", "pseudoprepaid"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{ReqTypes: []string{"prepaid", "pseudoprepaid"}}); 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, nil, nil, nil, nil, nil, nil, []string{"*out"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Directions: []string{"*out"}}); 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, nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Tenants: []string{"itsyscom.com"}}); 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, nil, nil, nil, nil, nil, nil, nil, []string{"itsyscom.com", "cgrates.org"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Tenants: []string{"itsyscom.com", "cgrates.org"}}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 8 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } // Filter on category - if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Categories: []string{"premium_call"}}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 1 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } - // Filter on multiple category - if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"premium_call", "call"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + // Filter on multiple categories + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Categories: []string{"premium_call", "call"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1002"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Accounts: []string{"1002"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1001", "1002"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Accounts: []string{"1001", "1002"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Subjects: []string{"1000"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []string{"1000", "1002"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{Subjects: []string{"1000", "1002"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - []string{"+498651"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{DestPrefixes: []string{"+498651"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - []string{"1001", "+498651"}, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{DestPrefixes: []string{"1001", "+498651"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, []string{"8001"}, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{RatedAccounts: []string{"8001"}}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, []string{"91001"}, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{RatedSubjects: []string{"91001"}}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 1 { 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, utils.Float64Pointer(0.0), false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{CostEnd: utils.Float64Pointer(0.0)}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 5 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -780,47 +730,39 @@ func TestPSQLGetStoredCdrs(t *testing.T) { } } // Filter on orderIdStart - if storedCdrs, err := psqlDb.GetStoredCdrs(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - &orderIdStart, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{OrderIdStart: orderIdStart}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - &orderIdStart, utils.Int64Pointer(orderIdEnd+1), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{OrderIdStart: orderIdStart, OrderIdEnd: orderIdEnd}); err != nil { t.Error(err.Error()) - } else if len(storedCdrs) != 5 { + } else if len(storedCdrs) != 4 { 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{AnswerTimeStart: &timeStart}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); 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, nil, nil, nil, nil, nil, []string{"rated"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{ReqTypes: []string{"rated"}, AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd}); 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, &timeStart, &timeEnd, nil, nil, nil, nil, nil, nil, true, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(&utils.CdrsFilter{AnswerTimeStart: &timeStart, AnswerTimeEnd: &timeEnd, IgnoreDerived: true}); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 0 { // ToDo: Recheck this value t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -835,8 +777,7 @@ func TestPSQLRemStoredCdrs(t *testing.T) { 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(new(utils.CdrsFilter)); err != nil { t.Error(err.Error()) } else if len(storedCdrs) != 7 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -857,8 +798,7 @@ func TestPSQLRemStoredCdrs(t *testing.T) { 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, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil); err != nil { + if storedCdrs, err := psqlDb.GetStoredCdrs(new(utils.CdrsFilter)); 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 985957fb3..ec6dda0af 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -742,15 +742,11 @@ func (self *SQLStorage) SetRatedCdr(storedCdr *utils.StoredCdr, extraInfo string return errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (self *SQLStorage) GetStoredCdrs(cgrIds, notCgrIds, runIds, notRunIds, tors, notTors, cdrHosts, notCdrHosts, cdrSources, notCdrSources, reqTypes, notReqTypes, directions, notDirections, - tenants, notTenants, categories, notCategories, accounts, notAccounts, subjects, notSubjects, destContains, notDestContains, ratedAccounts, notRatedAccounts, ratedSubjects, notRatedSubjects []string, - costs []float64, notCosts []float64, extraFields map[string]string, notExtraFields map[string]string, - orderIdStart, orderIdEnd *int64, sTimeStart, sTimeEnd, aTimeStart, aTimeEnd *time.Time, usageStart, usageEnd, ratedUsageStart, ratedUsageEnd, costStart, costEnd *float64, ignoreDerived bool, - pagination *utils.Paginator) ([]*utils.StoredCdr, error) { +func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*utils.StoredCdr, error) { var cdrs []*utils.StoredCdr // Select string var selectStr string - if ignoreDerived { // We use different tables to query account data in case of derived + if qryFltr.IgnoreDerived { // We use different tables to query account data in case of derived selectStr = fmt.Sprintf("%s.cgrid,%s.id,%s.tor,%s.accid,%s.cdrhost,%s.cdrsource,%s.reqtype,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.setup_time,%s.answer_time,%s.usage,%s.extra_fields,%s.runid,%s.account,%s.subject,%s.cost", utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, @@ -766,91 +762,91 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, notCgrIds, runIds, notRunIds, tors joinStr := fmt.Sprintf("LEFT JOIN %s ON %s.cgrid=%s.cgrid LEFT JOIN %s ON %s.cgrid=%s.cgrid LEFT JOIN %s ON %s.cgrid=%s.cgrid AND %s.runid=%s.runid", utils.TBL_CDRS_EXTRA, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA, utils.TBL_RATED_CDRS, utils.TBL_CDRS_PRIMARY, utils.TBL_RATED_CDRS, utils.TBL_COST_DETAILS, utils.TBL_RATED_CDRS, utils.TBL_COST_DETAILS, utils.TBL_RATED_CDRS, utils.TBL_COST_DETAILS) q := self.db.Table(utils.TBL_CDRS_PRIMARY).Select(selectStr).Joins(joinStr) - // Where section + // Query filter for _, tblName := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA, utils.TBL_COST_DETAILS, utils.TBL_RATED_CDRS} { q = q.Where(fmt.Sprintf("(%s.deleted_at IS NULL OR %s.deleted_at <= '0001-01-02')", tblName, tblName)) // Soft deletes } // Add filters, use in to replace the high number of ORs - if len(cgrIds) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid in (?)", cgrIds) + if len(qryFltr.CgrIds) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid in (?)", qryFltr.CgrIds) } - if len(notCgrIds) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid not in (?)", notCgrIds) + if len(qryFltr.NotCgrIds) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid not in (?)", qryFltr.NotCgrIds) } - if len(runIds) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".runid in (?)", runIds) + if len(qryFltr.RunIds) != 0 { + q = q.Where(utils.TBL_RATED_CDRS+".runid in (?)", qryFltr.RunIds) } - if len(notRunIds) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".runid not in (?)", notRunIds) + if len(qryFltr.NotRunIds) != 0 { + q = q.Where(utils.TBL_RATED_CDRS+".runid not in (?)", qryFltr.NotRunIds) } - if len(tors) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tor in (?)", tors) + if len(qryFltr.Tors) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".tor in (?)", qryFltr.Tors) } - if len(notTors) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tor not in (?)", notTors) + if len(qryFltr.NotTors) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".tor not in (?)", qryFltr.NotTors) } - if len(cdrHosts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost in (?)", cdrHosts) + if len(qryFltr.CdrHosts) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost in (?)", qryFltr.CdrHosts) } - if len(notCdrHosts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost not in (?)", notCdrHosts) + if len(qryFltr.NotCdrHosts) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost not in (?)", qryFltr.NotCdrHosts) } - if len(cdrSources) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource in (?)", cdrSources) + if len(qryFltr.CdrSources) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource in (?)", qryFltr.CdrSources) } - if len(notCdrSources) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource not in (?)", notCdrSources) + if len(qryFltr.NotCdrSources) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource not in (?)", qryFltr.NotCdrSources) } - if len(reqTypes) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".reqtype in (?)", reqTypes) + if len(qryFltr.ReqTypes) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".reqtype in (?)", qryFltr.ReqTypes) } - if len(notReqTypes) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".reqtype not in (?)", notReqTypes) + if len(qryFltr.NotReqTypes) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".reqtype not in (?)", qryFltr.NotReqTypes) } - if len(directions) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".direction in (?)", directions) + if len(qryFltr.Directions) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".direction in (?)", qryFltr.Directions) } - if len(notDirections) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".direction not in (?)", notDirections) + if len(qryFltr.NotDirections) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".direction not in (?)", qryFltr.NotDirections) } - if len(tenants) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tenant in (?)", tenants) + if len(qryFltr.Tenants) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".tenant in (?)", qryFltr.Tenants) } - if len(notTenants) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tenant not in (?)", notTenants) + if len(qryFltr.NotTenants) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".tenant not in (?)", qryFltr.NotTenants) } - if len(categories) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".category in (?)", categories) + if len(qryFltr.Categories) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".category in (?)", qryFltr.Categories) } - if len(notCategories) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".category not in (?)", notCategories) + if len(qryFltr.NotCategories) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".category not in (?)", qryFltr.NotCategories) } - if len(accounts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".account in (?)", accounts) + if len(qryFltr.Accounts) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".account in (?)", qryFltr.Accounts) } - if len(notAccounts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".account not in (?)", notAccounts) + if len(qryFltr.NotAccounts) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".account not in (?)", qryFltr.NotAccounts) } - if len(subjects) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".subject in (?)", subjects) + if len(qryFltr.Subjects) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".subject in (?)", qryFltr.Subjects) } - if len(notSubjects) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".subject not in (?)", notSubjects) + if len(qryFltr.NotSubjects) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".subject not in (?)", qryFltr.NotSubjects) } - if len(destContains) != 0 { // A bit ugly but still more readable than scopes provided by gorm + if len(qryFltr.DestPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm qIds := bytes.NewBufferString("(") - for idx, destPrefix := range destContains { + for idx, destPrefix := range qryFltr.DestPrefixes { if idx != 0 { qIds.WriteString(" OR") } - qIds.WriteString(fmt.Sprintf(" %s.destination LIKE '%%%s%%'", utils.TBL_CDRS_PRIMARY, destPrefix)) + qIds.WriteString(fmt.Sprintf(" %s.destination LIKE '%s%%'", utils.TBL_CDRS_PRIMARY, destPrefix)) } qIds.WriteString(" )") q = q.Where(qIds.String()) } - if len(notDestContains) != 0 { // A bit ugly but still more readable than scopes provided by gorm + if len(qryFltr.NotDestPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm qIds := bytes.NewBufferString("(") - for idx, destPrefix := range notDestContains { + for idx, destPrefix := range qryFltr.NotDestPrefixes { if idx != 0 { qIds.WriteString(" AND") } @@ -859,28 +855,28 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, notCgrIds, runIds, notRunIds, tors qIds.WriteString(" )") q = q.Where(qIds.String()) } - if len(ratedAccounts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".account in (?)", ratedAccounts) + if len(qryFltr.RatedAccounts) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".account in (?)", qryFltr.RatedAccounts) } - if len(notRatedAccounts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".account not in (?)", notRatedAccounts) + if len(qryFltr.NotRatedAccounts) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".account not in (?)", qryFltr.NotRatedAccounts) } - if len(ratedSubjects) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".subject in (?)", ratedSubjects) + if len(qryFltr.RatedSubjects) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".subject in (?)", qryFltr.RatedSubjects) } - if len(notRatedSubjects) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".subject not in (?)", notRatedSubjects) + if len(qryFltr.NotRatedSubjects) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".subject not in (?)", qryFltr.NotRatedSubjects) } - if len(costs) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".cost in (?)", costs) + if len(qryFltr.Costs) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".cost in (?)", qryFltr.Costs) } - if len(notCosts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".cost not in (?)", notCosts) + if len(qryFltr.NotCosts) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".cost not in (?)", qryFltr.NotCosts) } - if len(extraFields) != 0 { // Extra fields searches, implemented as contains in extra field + if len(qryFltr.ExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field qIds := bytes.NewBufferString("(") needOr := false - for field, value := range extraFields { + for field, value := range qryFltr.ExtraFields { if needOr { qIds.WriteString(" OR") } @@ -890,10 +886,10 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, notCgrIds, runIds, notRunIds, tors qIds.WriteString(" )") q = q.Where(qIds.String()) } - if len(notExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field + if len(qryFltr.NotExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field qIds := bytes.NewBufferString("(") needAnd := false - for field, value := range notExtraFields { + for field, value := range qryFltr.NotExtraFields { if needAnd { qIds.WriteString(" OR") } @@ -903,54 +899,56 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, notCgrIds, runIds, notRunIds, tors qIds.WriteString(" )") q = q.Where(qIds.String()) } - if orderIdStart != nil && *orderIdStart != 0 { // Keep backwards compatible by testing 0 value - q = q.Where(utils.TBL_CDRS_PRIMARY+".id >= ?", *orderIdStart) + if qryFltr.OrderIdStart != 0 { // Keep backwards compatible by testing 0 value + q = q.Where(utils.TBL_CDRS_PRIMARY+".id >= ?", qryFltr.OrderIdStart) } - if orderIdEnd != nil && *orderIdEnd != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".id < ?", *orderIdEnd) + if qryFltr.OrderIdEnd != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".id < ?", qryFltr.OrderIdEnd) } - if sTimeStart != nil { - q = q.Where(utils.TBL_CDRS_PRIMARY+".setup_time >= ?", sTimeStart) + if qryFltr.SetupTimeStart != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".setup_time >= ?", qryFltr.SetupTimeStart) } - if sTimeEnd != nil { - q = q.Where(utils.TBL_CDRS_PRIMARY+".setup_time < ?", sTimeEnd) + if qryFltr.SetupTimeEnd != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".setup_time < ?", qryFltr.SetupTimeEnd) } - if aTimeStart != nil && !aTimeStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time >= ?", aTimeStart) + if qryFltr.AnswerTimeStart != nil && !qryFltr.AnswerTimeStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 + q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time >= ?", qryFltr.AnswerTimeStart) } - if aTimeEnd != nil && !aTimeEnd.IsZero() { - q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time < ?", aTimeEnd) + if qryFltr.AnswerTimeEnd != nil && !qryFltr.AnswerTimeEnd.IsZero() { + q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time < ?", qryFltr.AnswerTimeEnd) } - if usageStart != nil { - q = q.Where(utils.TBL_CDRS_PRIMARY+".usage >= ?", usageStart) + if qryFltr.UsageStart != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".usage >= ?", qryFltr.UsageStart) } - if usageEnd != nil { - q = q.Where(utils.TBL_CDRS_PRIMARY+".usage < ?", usageEnd) + if qryFltr.UsageEnd != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".usage < ?", qryFltr.UsageEnd) } - if ratedUsageStart != nil { - q = q.Where(utils.TBL_RATED_CDRS+".usage >= ?", ratedUsageStart) + if qryFltr.RatedUsageStart != nil { + q = q.Where(utils.TBL_RATED_CDRS+".usage >= ?", qryFltr.RatedUsageStart) } - if ratedUsageEnd != nil { - q = q.Where(utils.TBL_RATED_CDRS+".usage < ?", ratedUsageEnd) + if qryFltr.RatedUsageEnd != nil { + q = q.Where(utils.TBL_RATED_CDRS+".usage < ?", qryFltr.RatedUsageEnd) } - if costStart != nil { - q = q.Where(utils.TBL_RATED_CDRS+".cost >= ?", *costStart) - if costEnd != nil { - q = q.Where(utils.TBL_RATED_CDRS+".cost < ?", *costEnd) + if qryFltr.CostStart != nil { + q = q.Where(utils.TBL_RATED_CDRS+".cost >= ?", *qryFltr.CostStart) + if qryFltr.CostEnd != nil { + q = q.Where(utils.TBL_RATED_CDRS+".cost < ?", *qryFltr.CostEnd) } - } else if costEnd != nil { // In case of both nil, we do not need to add any filter - if *costEnd == -1.0 { // Non-rated CDRs + } else if qryFltr.CostEnd != nil { // In case of both nil, we do not need to add any filter + if *qryFltr.CostEnd == -1.0 { // Non-rated CDRs q = q.Where(utils.TBL_RATED_CDRS + ".cost IS NULL") // Need to include it otherwise all CDRs will be returned } else { // Above limited CDRs, since costStart is empty, make sure we query also NULL cost - q = q.Where(fmt.Sprintf("( %s.cost IS NULL OR %s.cost < %f )", utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, *costEnd)) + q = q.Where(fmt.Sprintf("( %s.cost IS NULL OR %s.cost < %f )", utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, *qryFltr.CostEnd)) } } - if ignoreDerived { + if qryFltr.IgnoreDerived { q = q.Where(utils.TBL_RATED_CDRS+".runid = ?", utils.DEFAULT_RUNID) } - if pagination != nil { - offset, limit := pagination.GetLimits() - q = q.Offset(offset).Limit(limit) + if qryFltr.PaginatorOffset != 0 { + q = q.Offset(qryFltr.PaginatorOffset) + } + if qryFltr.PaginatorLimit != 0 { + q = q.Limit(qryFltr.PaginatorLimit) } // Execute query rows, err := q.Rows() diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 0b33d38ab..d27714cac 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -686,6 +686,47 @@ type AttrExpFileCdrs struct { SuppressCgrIds bool // Disable CgrIds reporting in reply/ExportedCgrIds and reply/UnexportedCgrIds } +func (self *AttrExpFileCdrs) AsCdrsFilter() (*CdrsFilter, error) { + var aTimeStart, aTimeEnd time.Time + var err error + if len(self.TimeStart) != 0 { + if aTimeStart, err = ParseTimeDetectLayout(self.TimeStart); err != nil { + return nil, err + } + } + if len(self.TimeEnd) != 0 { + if aTimeEnd, err = ParseTimeDetectLayout(self.TimeEnd); err != nil { + return nil, err + } + } + cdrFltr := &CdrsFilter{ + CgrIds: self.CgrIds, + RunIds: self.MediationRunIds, + Tors: self.TORs, + CdrHosts: self.CdrHosts, + CdrSources: self.CdrSources, + ReqTypes: self.ReqTypes, + Directions: self.Directions, + Tenants: self.Tenants, + Categories: self.Categories, + Accounts: self.Accounts, + Subjects: self.Subjects, + DestPrefixes: self.DestinationPrefixes, + RatedAccounts: self.RatedAccounts, + RatedSubjects: self.RatedSubjects, + OrderIdStart: self.OrderIdStart, + OrderIdEnd: self.OrderIdEnd, + AnswerTimeStart: &aTimeStart, + AnswerTimeEnd: &aTimeEnd, + } + if self.SkipRated { + cdrFltr.CostEnd = Float64Pointer(0.0) + } else if self.SkipErrors { + cdrFltr.CostEnd = Float64Pointer(-1.0) + } + return cdrFltr, nil +} + type ExportedFileCdrs struct { ExportedFilePath string // Full path to the newly generated export file TotalRecords int // Number of CDRs to be exported @@ -719,6 +760,47 @@ type AttrGetCdrs struct { Paginator } +func (self *AttrGetCdrs) AsCdrsFilter() (*CdrsFilter, error) { + var aTimeStart, aTimeEnd time.Time + var err error + if len(self.TimeStart) != 0 { + if aTimeStart, err = ParseTimeDetectLayout(self.TimeStart); err != nil { + return nil, err + } + } + if len(self.TimeEnd) != 0 { + if aTimeEnd, err = ParseTimeDetectLayout(self.TimeEnd); err != nil { + return nil, err + } + } + cdrFltr := &CdrsFilter{ + CgrIds: self.CgrIds, + RunIds: self.MediationRunIds, + Tors: self.TORs, + CdrHosts: self.CdrHosts, + CdrSources: self.CdrSources, + ReqTypes: self.ReqTypes, + Directions: self.Directions, + Tenants: self.Tenants, + Categories: self.Categories, + Accounts: self.Accounts, + Subjects: self.Subjects, + DestPrefixes: self.DestinationPrefixes, + RatedAccounts: self.RatedAccounts, + RatedSubjects: self.RatedSubjects, + OrderIdStart: self.OrderIdStart, + OrderIdEnd: self.OrderIdEnd, + AnswerTimeStart: &aTimeStart, + AnswerTimeEnd: &aTimeEnd, + } + if self.SkipRated { + cdrFltr.CostEnd = Float64Pointer(0.0) + } else if self.SkipErrors { + cdrFltr.CostEnd = Float64Pointer(-1.0) + } + return cdrFltr, nil +} + type AttrRemCdrs struct { CgrIds []string // List of CgrIds to remove from storeDb } @@ -790,3 +872,54 @@ type ExportedTPStats struct { ExportedFiles []string // List of exported files Compressed bool } + +// Filter used in engine.GetStoredCdrs +type CdrsFilter struct { + CgrIds []string // If provided, it will filter based on the cgrids present in list + NotCgrIds []string // Filter specific CgrIds out + RunIds []string // If provided, it will filter on mediation runid + NotRunIds []string // Filter specific runIds out + Tors []string // If provided, filter on TypeOfRecord + NotTors []string // Filter specific TORs out + CdrHosts []string // If provided, it will filter cdrhost + NotCdrHosts []string // Filter out specific cdr hosts + CdrSources []string // If provided, it will filter cdrsource + NotCdrSources []string // Filter out specific CDR sources + ReqTypes []string // If provided, it will fiter reqtype + NotReqTypes []string // Filter out specific request types + Directions []string // If provided, it will fiter direction + NotDirections []string // Filter out specific directions + Tenants []string // If provided, it will filter tenant + NotTenants []string // If provided, it will filter tenant + Categories []string // If provided, it will filter çategory + NotCategories []string // Filter out specific categories + Accounts []string // If provided, it will filter account + NotAccounts []string // Filter out specific Accounts + Subjects []string // If provided, it will filter the rating subject + NotSubjects []string // Filter out specific subjects + DestPrefixes []string // If provided, it will filter on destination prefix + NotDestPrefixes []string // Filter out specific destination prefixes + RatedAccounts []string // If provided, it will filter ratedaccount + NotRatedAccounts []string // Filter out specific RatedAccounts + RatedSubjects []string // If provided, it will filter the ratedsubject + NotRatedSubjects []string // Filter out specific RatedSubjects + Costs []float64 // Query based on costs specified + NotCosts []float64 // Filter out specific costs out from result + ExtraFields map[string]string // Query based on extra fields content + NotExtraFields map[string]string // Filter out based on extra fields content + OrderIdStart int64 // Export from this order identifier + OrderIdEnd int64 // Export smaller than this order identifier + SetupTimeStart *time.Time // Start of interval, bigger or equal than configured + SetupTimeEnd *time.Time // End interval, smaller than setupTime + AnswerTimeStart *time.Time // Start of interval, bigger or equal than configured + AnswerTimeEnd *time.Time // End interval, smaller than answerTime + UsageStart *float64 // Start of the usage interval (>=) + UsageEnd *float64 // End of the usage interval (<) + RatedUsageStart *float64 // Start of the ratedUsage interval (>=) + RatedUsageEnd *float64 // End of the ratedUsage interval (<) + CostStart *float64 // Start of the cost interval (>=) + CostEnd *float64 // End of the usage interval (<) + IgnoreDerived bool // Do not consider derived CDRs but original one + PaginatorOffset int // Start retrieving from this offset + PaginatorLimit int // Limit the number of items retrieved +}