diff --git a/apier/v1/cdre.go b/apier/v1/cdre.go index 9570b6d3e..d6967c287 100644 --- a/apier/v1/cdre.go +++ b/apier/v1/cdre.go @@ -185,9 +185,15 @@ func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.E if attr.MaskLength != nil { maskLen = *attr.MaskLength } - cdrs, err := self.CdrDb.GetStoredCdrs(attr.CgrIds, attr.MediationRunIds, attr.TORs, attr.CdrHosts, attr.CdrSources, attr.ReqTypes, attr.Directions, - attr.Tenants, attr.Categories, attr.Accounts, attr.Subjects, attr.DestinationPrefixes, attr.RatedAccounts, attr.RatedSubjects, attr.OrderIdStart, attr.OrderIdEnd, - tStart, tEnd, attr.SkipErrors, attr.SkipRated, false, nil) + var costStart, costEnd *float64 + if attr.SkipRated { + costEnd = utils.Float64Pointer(0.0) + } else if attr.SkipErrors { + costEnd = utils.Float64Pointer(-1.0) + } + 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) if err != nil { return err } else if len(cdrs) == 0 { diff --git a/apier/v1/cdrs.go b/apier/v1/cdrs.go index aa3e2a88d..c3a54a202 100644 --- a/apier/v1/cdrs.go +++ b/apier/v1/cdrs.go @@ -60,10 +60,18 @@ func (apier *ApierV1) GetCdrs(attrs utils.AttrGetCdrs, reply *[]*utils.CgrCdrOut return err } } - if cdrs, err := apier.CdrDb.GetStoredCdrs(attrs.CgrIds, attrs.MediationRunIds, attrs.TORs, attrs.CdrHosts, attrs.CdrSources, attrs.ReqTypes, attrs.Directions, - attrs.Tenants, attrs.Categories, attrs.Accounts, attrs.Subjects, attrs.DestinationPrefixes, attrs.RatedAccounts, attrs.RatedSubjects, - attrs.OrderIdStart, attrs.OrderIdEnd, tStart, tEnd, attrs.SkipErrors, attrs.SkipRated, false, &attrs.Paginator); err != nil { + 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 { return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if len(cdrs) == 0 { + *reply = make([]*utils.CgrCdrOut, 0) } else { for _, cdr := range cdrs { *reply = append(*reply, cdr.AsCgrCdrOut()) diff --git a/docs/cgrates_cfg.rst b/docs/cgrates_cfg.rst index c97f5f1c1..4a3343995 100644 --- a/docs/cgrates_cfg.rst +++ b/docs/cgrates_cfg.rst @@ -10,30 +10,30 @@ Bellow is the default configuration file which comes hardcoded into cgr-engine, [global] # ratingdb_type = redis # Rating subsystem database: . # ratingdb_host = 127.0.0.1 # Rating subsystem database host address. - # ratingdb_port = 6379 # Rating subsystem port to reach the database. + # ratingdb_port = 6379 # Rating subsystem port to reach the database. # ratingdb_name = 10 # Rating subsystem database name to connect to. - # ratingdb_user = # Rating subsystem username to use when connecting to database. - # ratingdb_passwd = # Rating subsystem password to use when connecting to database. + # ratingdb_user = # Rating subsystem username to use when connecting to database. + # ratingdb_passwd = # Rating subsystem password to use when connecting to database. # accountdb_type = redis # Accounting subsystem database: . # accountdb_host = 127.0.0.1 # Accounting subsystem database host address. # accountdb_port = 6379 # Accounting subsystem port to reach the database. # accountdb_name = 11 # Accounting subsystem database name to connect to. - # accountdb_user = # Accounting subsystem username to use when connecting to database. + # accountdb_user = # Accounting subsystem username to use when connecting to database. # accountdb_passwd = # Accounting subsystem password to use when connecting to database. # stordb_type = mysql # Stor database type to use: # stordb_host = 127.0.0.1 # The host to connect to. Values that start with / are for UNIX domain sockets. # stordb_port = 3306 # The port to reach the logdb. # stordb_name = cgrates # The name of the log database to connect to. - # stordb_user = cgrates # Username to use when connecting to stordb. + # stordb_user = cgrates # Username to use when connecting to stordb. # stordb_passwd = CGRateS.org # Password to use when connecting to stordb. - # dbdata_encoding = msgpack # The encoding used to store object data in strings: + # dbdata_encoding = msgpack # The encoding used to store object data in strings: # rpc_json_listen = 127.0.0.1:2012 # RPC JSON listening address # rpc_gob_listen = 127.0.0.1:2013 # RPC GOB listening address # http_listen = 127.0.0.1:2080 # HTTP listening address # default_reqtype = rated # Default request type to consider when missing from requests: <""|prepaid|postpaid|pseudoprepaid|rated>. # default_category = call # Default Type of Record to consider when missing from requests. # default_tenant = cgrates.org # Default Tenant to consider when missing from requests. - # default_subject = cgrates # Default rating Subject to consider when missing from requests. + # default_subject = cgrates # Default rating Subject to consider when missing from requests. # rounding_decimals = 10 # System level precision for floats # http_skip_tls_veify = false # If enabled Http Client will accept any TLS certificate # xmlcfg_path = # Path towards additional config defined in xml file @@ -53,53 +53,53 @@ Bellow is the default configuration file which comes hardcoded into cgr-engine, # extra_fields = # Extra fields to store in CDRs for non-generic CDRs # mediator = # Address where to reach the Mediator. Empty for disabling mediation. <""|internal> # cdrstats = # Address where to reach the cdrstats service: - # store_disable = false # When true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario + # store_disable = false # When true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario [cdre] # cdr_format = csv # Exported CDRs format # data_usage_multiply_factor = 0.0 # Multiply data usage before export (eg: convert from KBytes to Bytes) # cost_multiply_factor = 0.0 # Multiply cost before export (0.0 to disable), eg: add VAT # cost_rounding_decimals = -1 # Rounding decimals for Cost values. -1 to disable rounding - # cost_shift_digits = 0 # Shift digits in the cost on export (eg: convert from EUR to cents) - # mask_destination_id = # Destination id containing called addresses to be masked on export + # cost_shift_digits = 0 # Shift digits in the cost on export (eg: convert from EUR to cents) + # mask_destination_id = # Destination id containing called addresses to be masked on export # mask_length = 0 # Length of the destination suffix to be masked # export_dir = /var/log/cgrates/cdre # Path where the exported CDRs will be placed # export_template = cgrid,mediation_runid,tor,accid,reqtype,direction,tenant,category,account,subject,destination,setup_time,answer_time,usage,cost # Exported fields template <""|fld1,fld2|*xml:instance_name> [cdrc] - # enabled = false # Enable CDR client functionality - # cdrs = internal # Address where to reach CDR server. + # enabled = false # Enable CDR client functionality + # cdrs = internal # Address where to reach CDR server. # run_delay = 0 # Sleep interval in seconds between consecutive runs, 0 to use automation via inotify - # cdr_type = csv # CDR file format . + # cdr_type = csv # CDR file format . # csv_separator = , # Separator used in case of csv files. One character only supported and needs to be right after equal sign - # cdr_in_dir = /var/log/cgrates/cdrc/in # Absolute path towards the directory where the CDRs are stored. + # cdr_in_dir = /var/log/cgrates/cdrc/in # Absolute path towards the directory where the CDRs are stored. # cdr_out_dir = /var/log/cgrates/cdrc/out # Absolute path towards the directory where processed CDRs will be moved. - # cdr_source_id = csv # Free form field, tag identifying the source of the CDRs within CGRS database. - # tor_field = 2 # TypeOfRecord field identifier. Use index number in case of .csv cdrs. - # accid_field = 3 # Accounting id field identifier. Use index number in case of .csv cdrs. + # cdr_source_id = csv # Free form field, tag identifying the source of the CDRs within CGRS database. + # tor_field = 2 # TypeOfRecord field identifier. Use index number in case of .csv cdrs. + # accid_field = 3 # Accounting id field identifier. Use index number in case of .csv cdrs. # reqtype_field = 4 # Request type field identifier. Use index number in case of .csv cdrs. - # direction_field = 5 # Direction field identifier. Use index numbers in case of .csv cdrs. - # tenant_field = 6 # Tenant field identifier. Use index numbers in case of .csv cdrs. - # category_field = 7 # Type of Record field identifier. Use index numbers in case of .csv cdrs. + # direction_field = 5 # Direction field identifier. Use index numbers in case of .csv cdrs. + # tenant_field = 6 # Tenant field identifier. Use index numbers in case of .csv cdrs. + # category_field = 7 # Type of Record field identifier. Use index numbers in case of .csv cdrs. # account_field = 8 # Account field identifier. Use index numbers in case of .csv cdrs. # subject_field = 9 # Subject field identifier. Use index numbers in case of .csv CDRs. - # destination_field = 10 # Destination field identifier. Use index numbers in case of .csv cdrs. + # destination_field = 10 # Destination field identifier. Use index numbers in case of .csv cdrs. # setup_time_field = 11 # Setup time field identifier. Use index numbers in case of .csv cdrs. - # answer_time_field = 12 # Answer time field identifier. Use index numbers in case of .csv cdrs. - # usage_field = 13 # Usage field identifier. Use index numbers in case of .csv cdrs. - # extra_fields = # Extra fields identifiers. For .csv, format: :[...,:] + # answer_time_field = 12 # Answer time field identifier. Use index numbers in case of .csv cdrs. + # usage_field = 13 # Usage field identifier. Use index numbers in case of .csv cdrs. + # extra_fields = # Extra fields identifiers. For .csv, format: :[...,:] [mediator] - # enabled = false # Starts Mediator service: . - # reconnects = 3 # Number of reconnects to rater/cdrs before giving up. - # rater = internal # Address where to reach the Rater: - # cdrstats = internal # Address where to reach the cdrstats service: - # store_disable = false # When true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario + # enabled = false # Starts Mediator service: . + # reconnects = 3 # Number of reconnects to rater/cdrs before giving up. + # rater = internal # Address where to reach the Rater: + # cdrstats = internal # Address where to reach the cdrstats service: + # store_disable = false # When true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario [cdrstats] # enabled = false # Starts the cdrstats service: - # queue_length = 50 # Number of items in the stats buffer + # queue_length = 50 # Number of items in the stats buffer # time_window = 1h # Will only keep the CDRs who's call setup time is not older than time.Now()-TimeWindow # metrics = ASR, ACD, ACC # Stat metric ids to build # setup_interval = # Filter on CDR SetupTime @@ -109,14 +109,14 @@ Bellow is the default configuration file which comes hardcoded into cgr-engine, # req_types = # Filter on CDR ReqType fields # directions = # Filter on CDR Direction fields # tenants = # Filter on CDR Tenant fields - # categories = # Filter on CDR Category fields + # categories = # Filter on CDR Category fields # accounts = # Filter on CDR Account fields # subjects = # Filter on CDR Subject fields # destination_prefixes = # Filter on CDR Destination prefixes - # usage_interval = # Filter on CDR Usage + # usage_interval = # Filter on CDR Usage # mediation_run_ids = # Filter on CDR MediationRunId fields # rated_accounts = # Filter on CDR RatedAccount fields - # rated_subjects = # Filter on CDR RatedSubject fields + # rated_subjects = # Filter on CDR RatedSubject fields # cost_intervals = # Filter on CDR Cost [session_manager] @@ -133,10 +133,10 @@ Bellow is the default configuration file which comes hardcoded into cgr-engine, # server = 127.0.0.1:8021 # Adress where to connect to FreeSWITCH socket. # passwd = ClueCon # FreeSWITCH socket password. # reconnects = 5 # Number of attempts on connect failure. - # min_dur_low_balance = 5s # Threshold which will trigger low balance warnings for prepaid calls (needs to be lower than debit_interval) - # low_balance_ann_file = # File to be played when low balance is reached for prepaid calls - # empty_balance_context = # If defined, prepaid calls will be transfered to this context on empty balance - # empty_balance_ann_file = # File to be played before disconnecting prepaid calls on empty balance (applies only if no context defined) + # min_dur_low_balance = 5s # Threshold which will trigger low balance warnings for prepaid calls (needs to be lower than debit_interval) + # low_balance_ann_file = # File to be played when low balance is reached for prepaid calls + # empty_balance_context = # If defined, prepaid calls will be transfered to this context on empty balance + # empty_balance_ann_file = # File to be played before disconnecting prepaid calls on empty balance (applies only if no context defined) # cdr_extra_fields = # Extra fields to store in CDRs in case of processing them [opensips] @@ -147,16 +147,16 @@ Bellow is the default configuration file which comes hardcoded into cgr-engine, [derived_charging] # run_ids = # Identifiers of additional sessions control. - # run_filters = # List of cdr field filters for each run. - # reqtype_fields = # Name of request type fields to be used during additional sessions control <""|*default|field_name>. + # run_filters = # List of cdr field filters for each run. + # reqtype_fields = # Name of request type fields to be used during additional sessions control <""|*default|field_name>. # direction_fields = # Name of direction fields to be used during additional sessions control <""|*default|field_name>. # tenant_fields = # Name of tenant fields to be used during additional sessions control <""|*default|field_name>. # category_fields = # Name of tor fields to be used during additional sessions control <""|*default|field_name>. - # account_fields = # Name of account fields to be used during additional sessions control <""|*default|field_name>. - # subject_fields = # Name of fields to be used during additional sessions control <""|*default|field_name>. - # destination_fields = # Name of destination fields to be used during additional sessions control <""|*default|field_name>. + # account_fields = # Name of account fields to be used during additional sessions control <""|*default|field_name>. + # subject_fields = # Name of fields to be used during additional sessions control <""|*default|field_name>. + # destination_fields = # Name of destination fields to be used during additional sessions control <""|*default|field_name>. # setup_time_fields = # Name of setup_time fields to be used during additional sessions control <""|*default|field_name>. - # answer_time_fields = # Name of answer_time fields to be used during additional sessions control <""|*default|field_name>. + # answer_time_fields = # Name of answer_time fields to be used during additional sessions control <""|*default|field_name>. # usage_fields = # Name of usage fields to be used during additional sessions control <""|*default|field_name>. # combined_chargers = true # Combine accounts specific derived_chargers with server configured ones . @@ -172,5 +172,5 @@ Bellow is the default configuration file which comes hardcoded into cgr-engine, [mailer] # server = localhost # The server to use when sending emails out # auth_user = cgrates # Authenticate to email server using this user - # auth_passwd = CGRateS.org # Authenticate to email server with this password + # auth_passwd = CGRateS.org # Authenticate to email server with this password # from_address = cgr-mailer@localhost.localdomain # From address used when sending emails out diff --git a/engine/mediator.go b/engine/mediator.go index 1cc1eb807..54ea529bb 100644 --- a/engine/mediator.go +++ b/engine/mediator.go @@ -185,9 +185,20 @@ func (self *Mediator) RateCdr(storedCdr *utils.StoredCdr, sendToStats bool) erro return nil } -func (self *Mediator) RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects []string, orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, rerateErrors, rerateRated, sendToStats bool) error { - cdrs, err := self.cdrDb.GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects, - orderIdStart, orderIdEnd, timeStart, timeEnd, !rerateErrors, !rerateRated, true, nil) +func (self *Mediator) RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects []string, + orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, rerateErrors, rerateRated, sendToStats bool) error { + var costStart, costEnd *float64 + if rerateErrors { + costStart = utils.Float64Pointer(-1.0) + if !rerateRated { + costEnd = utils.Float64Pointer(0.0) + } + } 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) if err != nil { return err } diff --git a/engine/mediator_local_test.go b/engine/mediator_local_test.go index 376fc7512..cbbf1c7d6 100644 --- a/engine/mediator_local_test.go +++ b/engine/mediator_local_test.go @@ -57,7 +57,7 @@ var storDbType = flag.String("stordb_type", utils.MYSQL, "The type of the storDb var startDelay = flag.Int("delay_start", 300, "Number of miliseconds to it for rater to start and cache") var cfgPath = path.Join(*dataDir, "conf", "samples", "mediator_test1.cfg") -func TestInitRatingDb(t *testing.T) { +func TestMediInitRatingDb(t *testing.T) { if !*testLocal { return } @@ -76,7 +76,7 @@ func TestInitRatingDb(t *testing.T) { } // Empty tables before using them -func TestInitStorDb(t *testing.T) { +func TestMediInitStorDb(t *testing.T) { if !*testLocal { return } @@ -103,7 +103,7 @@ func TestInitStorDb(t *testing.T) { } // Finds cgr-engine executable and starts it with default configuration -func TestStartEngine(t *testing.T) { +func TestMediStartEngine(t *testing.T) { if !*testLocal { return } @@ -123,7 +123,7 @@ func TestStartEngine(t *testing.T) { } // Connect rpc client -func TestRpcConn(t *testing.T) { +func TestMediRpcConn(t *testing.T) { if !*testLocal { return } @@ -135,7 +135,7 @@ func TestRpcConn(t *testing.T) { } } -func TestPostCdrs(t *testing.T) { +func TestMediPostCdrs(t *testing.T) { if !*testLocal { return } @@ -157,12 +157,14 @@ func TestPostCdrs(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, 0, 0, time.Time{}, time.Time{}, false, false, false, nil); err != nil { + 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 { 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, 0, 0, time.Time{}, time.Time{}, true, false, false, nil); err != nil { + 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 { t.Error(err) } else if len(nonErrorCdrs) != 0 { t.Error(fmt.Sprintf("Unexpected number of CDRs stored: %d", len(nonErrorCdrs))) @@ -170,7 +172,7 @@ func TestPostCdrs(t *testing.T) { } // Directly inject CDRs into storDb -func TestInjectCdrs(t *testing.T) { +func TestMediInjectCdrs(t *testing.T) { if !*testLocal { return } @@ -185,12 +187,14 @@ func TestInjectCdrs(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, 0, 0, time.Time{}, time.Time{}, false, false, false, nil); err != nil { + 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 { 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, 0, 0, time.Time{}, time.Time{}, true, true, false, nil); err != nil { + 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 { 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))) @@ -198,7 +202,7 @@ func TestInjectCdrs(t *testing.T) { } // Test here LoadTariffPlanFromFolder -func TestLoadTariffPlanFromFolder(t *testing.T) { +func TestMediLoadTariffPlanFromFolder(t *testing.T) { if !*testLocal { return } @@ -212,7 +216,7 @@ func TestLoadTariffPlanFromFolder(t *testing.T) { } } -func TestRateCdrs(t *testing.T) { +func TestMediRateCdrs(t *testing.T) { if !*testLocal { return } @@ -222,14 +226,16 @@ func TestRateCdrs(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, 0, 0, time.Time{}, time.Time{}, true, true, false, nil); err != nil { + 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 { t.Error(err) - } else if len(nonRatedCdrs) != 0 { // All CDRs should be rated + } 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, 0, 0, time.Time{}, time.Time{}, false, true, false, nil); err != nil { + 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 { t.Error(err) - } else if len(errRatedCdrs) != 8 { // The first 2 with errors should be still there before rerating + } 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))) } if err := cgrRpc.Call("MediatorV1.RateCdrs", utils.AttrRateCdrs{RerateErrors: true}, &reply); err != nil { @@ -237,9 +243,10 @@ func TestRateCdrs(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, 0, 0, time.Time{}, time.Time{}, false, true, false, nil); err != nil { + 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 { t.Error(err) - } else if len(errRatedCdrs) != 4 { + } else if len(errRatedCdrs) != 2 { t.Error(fmt.Sprintf("Unexpected number of CDRs with errors: %d", len(errRatedCdrs))) } } @@ -281,7 +288,7 @@ func TestMediatePseudoprepaid(t *testing.T) { */ // Simply kill the engine after we are done with tests within this file -func TestStopEngine(t *testing.T) { +func TestMediStopEngine(t *testing.T) { if !*testLocal { return } diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 0280f0a29..0430dcd23 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -114,8 +114,11 @@ type CdrStorage interface { Storage SetCdr(*utils.StoredCdr) error SetRatedCdr(*utils.StoredCdr, string) error - GetStoredCdrs([]string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, []string, - int64, int64, time.Time, time.Time, bool, bool, bool, *utils.Paginator) ([]*utils.StoredCdr, 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) RemStoredCdrs([]string) error } diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 0ed70a16a..31618cc89 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 269b5794f..31892a15d 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -560,7 +560,8 @@ 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 8 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -568,7 +569,8 @@ func TestMySQLGetStoredCdrs(t *testing.T) { // 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 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 { t.Error(err.Error()) } else if len(storedCdrs) != 2 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -576,172 +578,192 @@ func TestMySQLGetStoredCdrs(t *testing.T) { // 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, []string{"prepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != 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 { 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, []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 { + 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 { 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, []string{utils.SMS}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []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 { + 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 { 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, []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 { + 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 { 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, []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 { + 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 { 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, []string{"UNKNOWN"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"UNKNOWN", "UNKNOWN2"}, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"prepaid"}, - nil, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"prepaid", "pseudoprepaid"}, nil, nil, nil, nil, nil, nil, nil, nil, - 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"*out"}, nil, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"itsyscom.com"}, nil, nil, nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"itsyscom.com", "cgrates.org"}, nil, nil, nil, nil, nil, nil, - 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 8 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } - // Filter on tor - if storedCdrs, err := mysqlDb.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 { + // 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 { t.Error(err.Error()) } else if len(storedCdrs) != 1 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } - // Filter on multiple tor - if storedCdrs, err := mysqlDb.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 { + // 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 { 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, []string{"1002"}, - nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"1001", "1002"}, - nil, nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"1000"}, - nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"1000", "1002"}, - nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"+498651"}, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"1001", "+498651"}, nil, nil, - 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"8001"}, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"91001"}, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 1 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) } - // Filter on ignoreErr - if storedCdrs, err := mysqlDb.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) != 3 { - 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, 0, 0, timeStart, timeEnd, false, true, false, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 5 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -756,41 +778,47 @@ 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, orderIdStart, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, orderIdStart, orderIdEnd+1, timeStart, timeEnd, - false, false, false, nil); err != nil { + 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 { 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 := mysqlDb.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 { + 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 { 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, []string{"rated"}, nil, nil, nil, nil, nil, - nil, nil, nil, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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, 0, 0, timeStart, timeEnd, false, false, true, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 0 { // ToDo: Recheck this value t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -801,12 +829,12 @@ func TestMySQLRemStoredCdrs(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 := 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 7 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -827,7 +855,8 @@ 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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 95ca4c8e5..e79fb2d18 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -562,7 +562,8 @@ 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 8 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -570,7 +571,8 @@ func TestPSQLGetStoredCdrs(t *testing.T) { // 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 { + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 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 { t.Error(err.Error()) } else if len(storedCdrs) != 2 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -578,172 +580,192 @@ func TestPSQLGetStoredCdrs(t *testing.T) { // 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + // 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 { 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 { + // 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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) != 3 { - 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 { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 5 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -758,41 +780,47 @@ 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, orderIdStart, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { 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 { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 0 { // ToDo: Recheck this value t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -807,8 +835,8 @@ func TestPSQLRemStoredCdrs(t *testing.T) { if err := psqlDb.RemStoredCdrs([]string{cgrIdB1}); err != nil { t.Error(err.Error()) } - var timeStart, timeEnd time.Time - 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 { + 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 { t.Error(err.Error()) } else if len(storedCdrs) != 7 { t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs) @@ -829,10 +857,10 @@ 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, 0, 0, timeStart, timeEnd, false, false, false, nil); err != nil { + 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 { 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 52cdc96b5..985957fb3 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -742,8 +742,11 @@ func (self *SQLStorage) SetRatedCdr(storedCdr *utils.StoredCdr, extraInfo string return errors.New(utils.ERR_NOT_IMPLEMENTED) } -func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes, ratedAccounts, ratedSubjects []string, - orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, ignoreErr, ignoreRated, ignoreDerived bool, pagination *utils.Paginator) ([]*utils.StoredCdr, error) { +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) { var cdrs []*utils.StoredCdr // Select string var selectStr string @@ -762,72 +765,185 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources // Join string 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) - // Start building query q := self.db.Table(utils.TBL_CDRS_PRIMARY).Select(selectStr).Joins(joinStr) // Where section 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)) // Do not consider soft deletes + 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(notCgrIds) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid not in (?)", notCgrIds) + } if len(runIds) != 0 { q = q.Where(utils.TBL_RATED_CDRS+".runid in (?)", runIds) } + if len(notRunIds) != 0 { + q = q.Where(utils.TBL_RATED_CDRS+".runid not in (?)", notRunIds) + } if len(tors) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".tor in (?)", tors) } + if len(notTors) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".tor not in (?)", notTors) + } if len(cdrHosts) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost in (?)", cdrHosts) } + if len(notCdrHosts) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost not in (?)", notCdrHosts) + } if len(cdrSources) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource in (?)", cdrSources) } + if len(notCdrSources) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource not in (?)", notCdrSources) + } if len(reqTypes) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".reqtype in (?)", reqTypes) } + if len(notReqTypes) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".reqtype not in (?)", notReqTypes) + } if len(directions) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".direction in (?)", directions) } + if len(notDirections) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".direction not in (?)", notDirections) + } if len(tenants) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".tenant in (?)", tenants) } + if len(notTenants) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".tenant not in (?)", notTenants) + } if len(categories) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".category in (?)", categories) } + if len(notCategories) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".category not in (?)", notCategories) + } if len(accounts) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".account in (?)", accounts) } + if len(notAccounts) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".account not in (?)", notAccounts) + } if len(subjects) != 0 { q = q.Where(utils.TBL_CDRS_PRIMARY+".subject in (?)", subjects) } + if len(notSubjects) != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".subject not in (?)", notSubjects) + } + if len(destContains) != 0 { // A bit ugly but still more readable than scopes provided by gorm + qIds := bytes.NewBufferString("(") + for idx, destPrefix := range destContains { + if idx != 0 { + qIds.WriteString(" OR") + } + 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 + qIds := bytes.NewBufferString("(") + for idx, destPrefix := range notDestContains { + if idx != 0 { + qIds.WriteString(" AND") + } + qIds.WriteString(fmt.Sprintf(" %s.destination not LIKE '%%%s%%'", utils.TBL_CDRS_PRIMARY, destPrefix)) + } + qIds.WriteString(" )") + q = q.Where(qIds.String()) + } if len(ratedAccounts) != 0 { q = q.Where(utils.TBL_COST_DETAILS+".account in (?)", ratedAccounts) } + if len(notRatedAccounts) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".account not in (?)", notRatedAccounts) + } if len(ratedSubjects) != 0 { q = q.Where(utils.TBL_COST_DETAILS+".subject in (?)", ratedSubjects) } - if orderIdStart != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".id >= ?", orderIdStart) + if len(notRatedSubjects) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".subject not in (?)", notRatedSubjects) } - if orderIdEnd != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".id < ?", orderIdEnd) + if len(costs) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".cost in (?)", costs) } - if !timeStart.IsZero() { - q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time >= ?", timeStart) + if len(notCosts) != 0 { + q = q.Where(utils.TBL_COST_DETAILS+".cost not in (?)", notCosts) } - if !timeEnd.IsZero() { - q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time < ?", timeEnd) - } - if ignoreRated { // ToDo: replace here with specific cost query - if ignoreErr { - q = q.Where(utils.TBL_RATED_CDRS + ".cost IS NULL") - } else { - q = q.Where(fmt.Sprintf("(%s.cost=-1 OR %s.cost IS NULL)", utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS)) + if len(extraFields) != 0 { // Extra fields searches, implemented as contains in extra field + qIds := bytes.NewBufferString("(") + needOr := false + for field, value := range extraFields { + if needOr { + qIds.WriteString(" OR") + } + qIds.WriteString(fmt.Sprintf(` %s.extra_fields LIKE '%%"%s":"%s"%%'`, utils.TBL_CDRS_EXTRA, field, value)) + needOr = true + } + qIds.WriteString(" )") + q = q.Where(qIds.String()) + } + if len(notExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field + qIds := bytes.NewBufferString("(") + needAnd := false + for field, value := range notExtraFields { + if needAnd { + qIds.WriteString(" OR") + } + qIds.WriteString(fmt.Sprintf(` %s.extra_fields LIKE '%%"%s":"%s"%%'`, utils.TBL_CDRS_EXTRA, field, value)) + needAnd = true + } + 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 orderIdEnd != nil && *orderIdEnd != 0 { + q = q.Where(utils.TBL_CDRS_PRIMARY+".id < ?", *orderIdEnd) + } + if sTimeStart != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".setup_time >= ?", sTimeStart) + } + if sTimeEnd != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".setup_time < ?", sTimeEnd) + } + if aTimeStart != nil && !aTimeStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 + q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time >= ?", aTimeStart) + } + if aTimeEnd != nil && !aTimeEnd.IsZero() { + q = q.Where(utils.TBL_CDRS_PRIMARY+".answer_time < ?", aTimeEnd) + } + if usageStart != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".usage >= ?", usageStart) + } + if usageEnd != nil { + q = q.Where(utils.TBL_CDRS_PRIMARY+".usage < ?", usageEnd) + } + if ratedUsageStart != nil { + q = q.Where(utils.TBL_RATED_CDRS+".usage >= ?", ratedUsageStart) + } + if ratedUsageEnd != nil { + q = q.Where(utils.TBL_RATED_CDRS+".usage < ?", 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) + } + } else if costEnd != nil { // In case of both nil, we do not need to add any filter + if *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)) } - } else if ignoreErr { - q = q.Where(utils.TBL_RATED_CDRS+".cost <> ?", -1) } if ignoreDerived { q = q.Where(utils.TBL_RATED_CDRS+".runid = ?", utils.DEFAULT_RUNID) @@ -836,17 +952,6 @@ func (self *SQLStorage) GetStoredCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources offset, limit := pagination.GetLimits() q = q.Offset(offset).Limit(limit) } - if len(destPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm - qIds := bytes.NewBufferString("(") - for idx, destPrefix := range destPrefixes { - if idx != 0 { - qIds.WriteString(" OR") - } - qIds.WriteString(fmt.Sprintf(" %s.destination LIKE '%s%%'", utils.TBL_CDRS_PRIMARY, destPrefix)) - } - qIds.WriteString(" )") - q = q.Where(qIds.String()) - } // Execute query rows, err := q.Rows() if err != nil { diff --git a/utils/coreutils.go b/utils/coreutils.go index fe982e523..7d4279fb5 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -327,3 +327,11 @@ func StringPointer(str string) *string { func IntPointer(i int) *int { return &i } + +func Int64Pointer(i int64) *int64 { + return &i +} + +func Float64Pointer(f float64) *float64 { + return &f +}