diff --git a/engine/storage_cdrs_it_test.go b/engine/storage_cdrs_it_test.go index 4b0a5a8c4..d9aac63a1 100644 --- a/engine/storage_cdrs_it_test.go +++ b/engine/storage_cdrs_it_test.go @@ -799,46 +799,46 @@ func testGetCDRs(cfg *config.CGRConfig) error { break } if CDRs[i].OrderID < CDRs[i+1].OrderID { - return fmt.Errorf("%+v should be greater than %+v \n", CDRs[i].OrderID, CDRs[i+1].OrderID) + return fmt.Errorf("testGetCDRs #95 %+v should be greater than %+v \n", CDRs[i].OrderID, CDRs[i+1].OrderID) } } } //Filter by OrderID ascendent if CDRs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{OrderBy: "OrderID"}, false); err != nil { - return fmt.Errorf("testGetCDRs #95, err: %v", err) + return fmt.Errorf("testGetCDRs #96, err: %v", err) } else { for i := range CDRs { if i+1 > len(CDRs)-1 { break } if CDRs[i].OrderID > CDRs[i+1].OrderID { - return fmt.Errorf("%+v sould be smaller than %+v \n", CDRs[i].OrderID, CDRs[i+1].OrderID) + return fmt.Errorf("testGetCDRs #96 %+v sould be smaller than %+v \n", CDRs[i].OrderID, CDRs[i+1].OrderID) } } } //Filter by Cost descendent if CDRs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{OrderBy: "Cost;desc"}, false); err != nil { - return fmt.Errorf("testGetCDRs #95, err: %v", err) + return fmt.Errorf("testGetCDRs #97, err: %v", err) } else { for i := range CDRs { if i+1 > len(CDRs)-1 { break } if CDRs[i].Cost < CDRs[i+1].Cost { - return fmt.Errorf("%+v should be greater than %+v \n", CDRs[i].Cost, CDRs[i+1].Cost) + return fmt.Errorf("testGetCDRs #97 %+v should be greater than %+v \n", CDRs[i].Cost, CDRs[i+1].Cost) } } } //Filter by Cost ascendent if CDRs, _, err := cdrStorage.GetCDRs(&utils.CDRsFilter{OrderBy: "Cost"}, false); err != nil { - return fmt.Errorf("testGetCDRs #95, err: %v", err) + return fmt.Errorf("testGetCDRs #98, err: %v", err) } else { for i := range CDRs { if i+1 > len(CDRs)-1 { break } if CDRs[i].Cost > CDRs[i+1].Cost { - return fmt.Errorf("%+v sould be smaller than %+v \n", CDRs[i].Cost, CDRs[i+1].Cost) + return fmt.Errorf("testGetCDRs #98 %+v sould be smaller than %+v \n", CDRs[i].Cost, CDRs[i+1].Cost) } } } diff --git a/engine/storage_internal_stordb.go b/engine/storage_internal_stordb.go index 2751906e5..a90cc29a2 100644 --- a/engine/storage_internal_stordb.go +++ b/engine/storage_internal_stordb.go @@ -19,6 +19,8 @@ along with this program. If not, see package engine import ( + "fmt" + "sort" "strings" "github.com/cgrates/cgrates/utils" @@ -937,36 +939,6 @@ func (iDB *InternalDB) GetCDRs(filter *utils.CDRsFilter, remove bool) (cdrs []*C } } } - //check if we have ExtraFields - if len(filter.ExtraFields) != 0 { - for extFldID, extrFldVal := range filter.ExtraFields { - // need to discuss about this case - if extrFldVal == utils.MetaExists { - - } - grpMpIDs := make(utils.StringMap) - grpIDs := iDB.db.GetGroupItemIDs(utils.CDRsTBL, utils.ConcatenatedKey(extFldID, extrFldVal)) - for _, id := range grpIDs { - grpMpIDs[id] = true - } - - if len(grpMpIDs) == 0 { - return nil, 0, utils.ErrNotFound - } - if cdrMpIDs == nil { - cdrMpIDs = grpMpIDs - } else { - for id := range cdrMpIDs { - if !grpMpIDs.HasKey(id) { - delete(cdrMpIDs, id) - if len(cdrMpIDs) == 0 { - return nil, 0, utils.ErrNotFound - } - } - } - } - } - } if cdrMpIDs == nil { cdrMpIDs = utils.StringMapFromSlice(iDB.db.GetItemIDs(utils.CDRsTBL, utils.EmptyString)) @@ -1005,24 +977,6 @@ func (iDB *InternalDB) GetCDRs(filter *utils.CDRsFilter, remove bool) (cdrs []*C } } } - //check if we have ExtraFields - if len(filter.NotExtraFields) != 0 { - for notExtFldID, notExtFlddVal := range filter.NotExtraFields { - // need to discuss about this case - if notExtFlddVal == utils.MetaExists { - - } - grpIDs := iDB.db.GetGroupItemIDs(utils.CDRsTBL, utils.ConcatenatedKey(notExtFldID, notExtFlddVal)) - for _, id := range grpIDs { - if cdrMpIDs.HasKey(id) { - delete(cdrMpIDs, id) - if len(cdrMpIDs) == 0 { - return nil, 0, utils.ErrNotFound - } - } - } - } - } if len(cdrMpIDs) == 0 { return nil, 0, utils.ErrNotFound @@ -1136,6 +1090,41 @@ func (iDB *InternalDB) GetCDRs(filter *utils.CDRsFilter, remove bool) (cdrs []*C } } } + if len(filter.ExtraFields) != 0 { + passFilter := true + for extFldID, extFldVal := range filter.ExtraFields { + if extFldVal == utils.MetaExists { + if _, has := cdr.ExtraFields[extFldID]; !has { + passFilter = false + break + } + } else if cdr.ExtraFields[extFldID] != extFldVal { + passFilter = false + break + } + + } + if !passFilter { + continue + } + } + if len(filter.NotExtraFields) != 0 { + passFilter := true + for notExtFldID, notExtFldVal := range filter.NotExtraFields { + if notExtFldVal == utils.MetaExists { + if _, has := cdr.ExtraFields[notExtFldID]; has { + passFilter = false + break + } + } else if cdr.ExtraFields[notExtFldID] == notExtFldVal { + passFilter = false + break + } + } + if !passFilter { + continue + } + } if filter.Paginator.Offset != nil { if paginatorOffsetCounter <= *filter.Paginator.Offset { @@ -1161,6 +1150,73 @@ func (iDB *InternalDB) GetCDRs(filter *utils.CDRsFilter, remove bool) (cdrs []*C } return nil, 0, nil } + if filter.OrderBy != "" { + separateVals := strings.Split(filter.OrderBy, utils.INFIELD_SEP) + ascendent := true + if len(separateVals) == 2 && separateVals[1] == "desc" { + ascendent = false + } + switch separateVals[0] { + case utils.OrderID: + if ascendent { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].OrderID < cdrs[j].OrderID + }) + } else { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].OrderID > cdrs[j].OrderID + }) + } + + case utils.AnswerTime: + if ascendent { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].AnswerTime.Before(cdrs[j].AnswerTime) + }) + } else { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].AnswerTime.After(cdrs[j].AnswerTime) + }) + } + + case utils.SetupTime: + if ascendent { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].SetupTime.Before(cdrs[j].SetupTime) + }) + } else { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].SetupTime.After(cdrs[j].SetupTime) + }) + } + + case utils.Usage: + if ascendent { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].Usage < cdrs[j].Usage + }) + } else { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].Usage > cdrs[j].Usage + }) + } + + case utils.Cost: + if ascendent { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].Cost < cdrs[j].Cost + }) + } else { + sort.Slice(cdrs, func(i, j int) bool { + return cdrs[i].Cost > cdrs[j].Cost + }) + } + + default: + return nil, 0, fmt.Errorf("Invalid value : %s", separateVals[0]) + } + + } return }