From 21ac1962222942fd1a1373989883ea7a2c8f765c Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Wed, 4 Nov 2015 17:20:19 +0200 Subject: [PATCH] tables unified, normal tests passing --- cdrc/cdrc_local_test.go | 6 +- data/storage/mysql/create_cdrs_tables.sql | 88 +-- data/storage/postgres/create_cdrs_tables.sql | 131 +--- engine/models.go | 74 +- engine/storage_mysql.go | 86 +-- engine/storage_mysql_local_test.go | 6 +- engine/storage_postgres.go | 99 --- engine/storage_psql_local_test.go | 6 +- engine/storage_sql.go | 711 +++++-------------- general_tests/multiplecdrc_local_test.go | 6 +- utils/consts.go | 5 +- 11 files changed, 224 insertions(+), 994 deletions(-) diff --git a/cdrc/cdrc_local_test.go b/cdrc/cdrc_local_test.go index fb3737c32..1fa731eae 100644 --- a/cdrc/cdrc_local_test.go +++ b/cdrc/cdrc_local_test.go @@ -121,10 +121,8 @@ func TestCsvLclEmptyTables(t *testing.T) { return // No point in going further } } - for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { - if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil { - t.Fatal(err.Error()) - } + if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", utils.TBL_CDRS)); err != nil { + t.Fatal(err.Error()) } } diff --git a/data/storage/mysql/create_cdrs_tables.sql b/data/storage/mysql/create_cdrs_tables.sql index ac7dc3088..62bc93fd8 100644 --- a/data/storage/mysql/create_cdrs_tables.sql +++ b/data/storage/mysql/create_cdrs_tables.sql @@ -1,13 +1,14 @@ -- --- Table structure for table `cdrs_primary` +-- Table structure for table `cdrs` -- -DROP TABLE IF EXISTS cdrs_primary; +DROP TABLE IF EXISTS cdrs; CREATE TABLE cdrs_primary ( id int(11) NOT NULL AUTO_INCREMENT, cgrid char(40) NOT NULL, - tor varchar(16) NOT NULL, + runid varchar(64) NOT NULL, + tor varchar(16) NOT NULL, accid varchar(64) NOT NULL, cdrhost varchar(64) NOT NULL, cdrsource varchar(64) NOT NULL, @@ -24,85 +25,16 @@ CREATE TABLE cdrs_primary ( `usage` DECIMAL(30,9) NOT NULL, supplier varchar(128) NOT NULL, disconnect_cause varchar(64) NOT NULL, + extra_fields text NOT NULL, + cost DECIMAL(20,4) NOT NULL, + timespans text, + cost_source varchar(64) NOT NULL, + extra_info text, created_at TIMESTAMP, + updated_at TIMESTAMP, deleted_at TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY cgrid (cgrid), KEY answer_time_idx (answer_time), KEY deleted_at_idx (deleted_at) - ); - --- --- Table structure for table `cdrs_extra` --- - -DROP TABLE IF EXISTS cdrs_extra; -CREATE TABLE cdrs_extra ( - id int(11) NOT NULL AUTO_INCREMENT, - cgrid char(40) NOT NULL, - extra_fields text NOT NULL, - created_at TIMESTAMP, - deleted_at TIMESTAMP, - PRIMARY KEY (id), - UNIQUE KEY cgrid (cgrid), - KEY deleted_at_idx (deleted_at) -); - --- --- Table structure for table `cost_details` --- - -DROP TABLE IF EXISTS cost_details; -CREATE TABLE cost_details ( - id int(11) NOT NULL AUTO_INCREMENT, - cgrid char(40) NOT NULL, - runid varchar(64) NOT NULL, - tor varchar(16) NOT NULL, - direction varchar(8) NOT NULL, - tenant varchar(128) NOT NULL, - category varchar(32) NOT NULL, - account varchar(128) NOT NULL, - subject varchar(128) NOT NULL, - destination varchar(128) NOT NULL, - cost DECIMAL(20,4) NOT NULL, - timespans text, - cost_source varchar(64) NOT NULL, - created_at TIMESTAMP, - updated_at TIMESTAMP, - deleted_at TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `costid` (`cgrid`,`runid`), - KEY deleted_at_idx (deleted_at) -); - --- --- Table structure for table `rated_cdrs` --- -DROP TABLE IF EXISTS rated_cdrs; -CREATE TABLE `rated_cdrs` ( - id int(11) NOT NULL AUTO_INCREMENT, - cgrid char(40) NOT NULL, - runid varchar(64) NOT NULL, - reqtype varchar(24) NOT NULL, - direction varchar(8) NOT NULL, - tenant varchar(64) NOT NULL, - category varchar(32) NOT NULL, - account varchar(128) NOT NULL, - subject varchar(128) NOT NULL, - destination varchar(128) NOT NULL, - setup_time datetime NOT NULL, - pdd DECIMAL(12,9) NOT NULL, - answer_time datetime NOT NULL, - `usage` DECIMAL(30,9) NOT NULL, - supplier varchar(128) NOT NULL, - disconnect_cause varchar(64) NOT NULL, - cost DECIMAL(20,4) DEFAULT NULL, - extra_info text, - created_at TIMESTAMP, - updated_at TIMESTAMP, - deleted_at TIMESTAMP, - PRIMARY KEY (`id`), - UNIQUE KEY `costid` (`cgrid`,`runid`), - KEY deleted_at_idx (deleted_at) -); \ No newline at end of file diff --git a/data/storage/postgres/create_cdrs_tables.sql b/data/storage/postgres/create_cdrs_tables.sql index 4aa36828f..6dd194b9b 100644 --- a/data/storage/postgres/create_cdrs_tables.sql +++ b/data/storage/postgres/create_cdrs_tables.sql @@ -1,103 +1,36 @@ - -- --- Table structure for table `cdrs_primary` +-- Table structure for table `cdrs` -- -DROP TABLE IF EXISTS cdrs_primary; -CREATE TABLE cdrs_primary ( - id SERIAL PRIMARY KEY, - cgrid CHAR(40) NOT NULL, - tor VARCHAR(16) NOT NULL, - accid VARCHAR(64) NOT NULL, - cdrhost VARCHAR(64) NOT NULL, - cdrsource VARCHAR(64) NOT NULL, - reqtype VARCHAR(24) NOT NULL, - direction VARCHAR(8) NOT NULL, - tenant VARCHAR(64) NOT NULL, - category VARCHAR(32) NOT NULL, - account VARCHAR(128) NOT NULL, - subject VARCHAR(128) NOT NULL, - destination VARCHAR(128) NOT NULL, - setup_time TIMESTAMP NOT NULL, - pdd NUMERIC(12,9) NOT NULL, - answer_time TIMESTAMP NOT NULL, - usage NUMERIC(30,9) NOT NULL, - supplier VARCHAR(128) NOT NULL, - disconnect_cause VARCHAR(64) NOT NULL, - created_at TIMESTAMP, - deleted_at TIMESTAMP, - UNIQUE (cgrid) +DROP TABLE IF EXISTS cdrs; +CREATE TABLE cdrs ( + id SERIAL PRIMARY KEY, + cgrid CHAR(40) NOT NULL, + runid VARCHAR(64) NOT NULL, + tor VARCHAR(16) NOT NULL, + accid VARCHAR(64) NOT NULL, + cdrhost VARCHAR(64) NOT NULL, + cdrsource VARCHAR(64) NOT NULL, + reqtype VARCHAR(24) NOT NULL, + direction VARCHAR(8) NOT NULL, + tenant VARCHAR(64) NOT NULL, + category VARCHAR(32) NOT NULL, + account VARCHAR(128) NOT NULL, + subject VARCHAR(128) NOT NULL, + destination VARCHAR(128) NOT NULL, + setup_time TIMESTAMP NOT NULL, + pdd NUMERIC(12,9) NOT NULL, + answer_time TIMESTAMP NOT NULL, + usage NUMERIC(30,9) NOT NULL, + supplier VARCHAR(128) NOT NULL, + disconnect_cause VARCHAR(64) NOT NULL, + extra_fields jsonb NOT NULL, + cost NUMERIC(20,4) DEFAULT NULL, + timespans jsonb, + cost_source VARCHAR(64) NOT NULL, + extra_info text, + created_at TIMESTAMP, + updated_at TIMESTAMP, + deleted_at TIMESTAMP, + UNIQUE (cgrid) ); -CREATE INDEX answer_time_idx ON cdrs_primary (answer_time); -CREATE INDEX deleted_at_cp_idx ON cdrs_primary (deleted_at); - --- --- Table structure for table `cdrs_extra` --- - -DROP TABLE IF EXISTS cdrs_extra; -CREATE TABLE cdrs_extra ( - id SERIAL PRIMARY KEY, - cgrid CHAR(40) NOT NULL, - extra_fields jsonb NOT NULL, - created_at TIMESTAMP, - deleted_at TIMESTAMP, - UNIQUE (cgrid) -); -CREATE INDEX deleted_at_ce_idx ON cdrs_extra (deleted_at); - --- --- Table structure for table `cost_details` --- - -DROP TABLE IF EXISTS cost_details; -CREATE TABLE cost_details ( - id SERIAL PRIMARY KEY, - cgrid CHAR(40) NOT NULL, - runid VARCHAR(64) NOT NULL, - tor VARCHAR(16) NOT NULL, - direction VARCHAR(8) NOT NULL, - tenant VARCHAR(128) NOT NULL, - category VARCHAR(32) NOT NULL, - account VARCHAR(128) NOT NULL, - subject VARCHAR(128) NOT NULL, - destination VARCHAR(128) NOT NULL, - cost NUMERIC(20,4) NOT NULL, - timespans jsonb, - cost_source VARCHAR(64) NOT NULL, - created_at TIMESTAMP, - updated_at TIMESTAMP, - deleted_at TIMESTAMP, - UNIQUE (cgrid, runid) -); -CREATE INDEX deleted_at_cd_idx ON cost_details (deleted_at); - --- --- Table structure for table `rated_cdrs` --- -DROP TABLE IF EXISTS rated_cdrs; -CREATE TABLE rated_cdrs ( - id SERIAL PRIMARY KEY, - cgrid CHAR(40) NOT NULL, - runid VARCHAR(64) NOT NULL, - reqtype VARCHAR(24) NOT NULL, - direction VARCHAR(8) NOT NULL, - tenant VARCHAR(64) NOT NULL, - category VARCHAR(32) NOT NULL, - account VARCHAR(128) NOT NULL, - subject VARCHAR(128) NOT NULL, - destination VARCHAR(128) NOT NULL, - setup_time TIMESTAMP NOT NULL, - pdd NUMERIC(12,9) NOT NULL, - answer_time TIMESTAMP NOT NULL, - usage NUMERIC(30,9) NOT NULL, - supplier VARCHAR(128) NOT NULL, - disconnect_cause VARCHAR(64) NOT NULL, - cost NUMERIC(20,4) DEFAULT NULL, - extra_info text, - created_at TIMESTAMP, - updated_at TIMESTAMP, - deleted_at TIMESTAMP, - UNIQUE (cgrid, runid) -); -CREATE INDEX deleted_at_rc_idx ON rated_cdrs (deleted_at); diff --git a/engine/models.go b/engine/models.go index 59aff1737..d8c1ff38e 100644 --- a/engine/models.go +++ b/engine/models.go @@ -162,7 +162,7 @@ type TpAction struct { Categories string `index:"6" re:""` DestinationTags string `index:"7" re:"\*any|\w+\s*"` RatingSubject string `index:"8" re:"\w+\s*"` - SharedGroups string `index:"9" re:"[0-9A-Za-z_;]*"` + SharedGroups string `index:"9" re:"[0-9A-Za-z_;]*"` ExpiryTime string `index:"10" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"` TimingTags string `index:"11" re:"[0-9A-Za-z_;]*|\*any"` Units float64 `index:"12" re:"\d+\s*"` @@ -197,7 +197,7 @@ type TpActionTrigger struct { BalanceCategories string `index:"9" re:""` BalanceDestinationTags string `index:"10" re:"\w+|\*any"` BalanceRatingSubject string `index:"11" re:"\w+|\*any"` - BalanceSharedGroups string `index:"12" re:"\w+|\*any"` + BalanceSharedGroups string `index:"12" re:"\w+|\*any"` BalanceExpiryTime string `index:"13" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"` BalanceTimingTags string `index:"14" re:"[0-9A-Za-z_;]*|\*any"` BalanceWeight float64 `index:"15" re:"\d+\.?\d*"` @@ -390,9 +390,10 @@ func (ta *TpAlias) GetId() string { return utils.ConcatenatedKey(ta.Direction, ta.Tenant, ta.Category, ta.Account, ta.Subject, ta.Context) } -type TblCdrsPrimary struct { +type TblCdrs struct { Id int64 Cgrid string + Runid string Tor string Accid string Cdrhost string @@ -410,73 +411,16 @@ type TblCdrsPrimary struct { Usage float64 Supplier string DisconnectCause string - CreatedAt time.Time - DeletedAt time.Time -} - -func (t TblCdrsPrimary) TableName() string { - return utils.TBL_CDRS_PRIMARY -} - -type TblCdrsExtra struct { - Id int64 - Cgrid string - ExtraFields string - CreatedAt time.Time - DeletedAt time.Time -} - -func (t TblCdrsExtra) TableName() string { - return utils.TBL_CDRS_EXTRA -} - -type TblCostDetail struct { - Id int64 - Cgrid string - Runid string - Tor string - Direction string - Tenant string - Category string - Account string - Subject string - Destination string - Cost float64 - Timespans string - CostSource string - CreatedAt time.Time - UpdatedAt time.Time - DeletedAt time.Time -} - -func (t TblCostDetail) TableName() string { - return utils.TBL_COST_DETAILS -} - -type TblRatedCdr struct { - Id int64 - Cgrid string - Runid string - Reqtype string - Direction string - Tenant string - Category string - Account string - Subject string - Destination string - SetupTime time.Time - Pdd float64 - AnswerTime time.Time - Usage float64 - Supplier string - DisconnectCause string + ExtraFields string Cost float64 + Timespans string + CostSource string ExtraInfo string CreatedAt time.Time UpdatedAt time.Time DeletedAt time.Time } -func (t TblRatedCdr) TableName() string { - return utils.TBL_RATED_CDRS +func (t TblCdrs) TableName() string { + return utils.TBL_CDRS } diff --git a/engine/storage_mysql.go b/engine/storage_mysql.go index 539a242e1..38310ed16 100644 --- a/engine/storage_mysql.go +++ b/engine/storage_mysql.go @@ -19,15 +19,15 @@ along with this program. If not, see package engine import ( - "encoding/json" "fmt" - "path" - "time" - "github.com/cgrates/cgrates/utils" "github.com/jinzhu/gorm" ) +type MySQLStorage struct { + *SQLStorage +} + func NewMySQLStorage(host, port, name, user, password string, maxConn, maxIdleConn int) (*MySQLStorage, error) { connectString := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&loc=Local&parseTime=true", user, password, host, port, name) db, err := gorm.Open("mysql", connectString) @@ -43,81 +43,3 @@ func NewMySQLStorage(host, port, name, user, password string, maxConn, maxIdleCo return &MySQLStorage{&SQLStorage{Db: db.DB(), db: db}}, nil } - -type MySQLStorage struct { - *SQLStorage -} - -func (self *MySQLStorage) Flush(scriptsPath string) (err error) { - for _, scriptName := range []string{utils.CREATE_CDRS_TABLES_SQL, utils.CREATE_TARIFFPLAN_TABLES_SQL} { - if err := self.CreateTablesFromScript(path.Join(scriptsPath, scriptName)); err != nil { - return err - } - } - for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { - if _, err := self.Db.Query(fmt.Sprintf("SELECT 1 FROM %s", tbl)); err != nil { - return err - } - } - return nil -} - -func (self *MySQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) (err error) { - if cc == nil { - return nil - } - tss, err := json.Marshal(cc.Timespans) - if err != nil { - utils.Logger.Err(fmt.Sprintf("Error marshalling timespans to json: %v", err)) - return err - } - _, err = self.Db.Exec(fmt.Sprintf("INSERT INTO %s (cgrid,runid,tor,direction,tenant,category,account,subject,destination,cost,timespans,cost_source,created_at) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s',%f,'%s','%s','%s') ON DUPLICATE KEY UPDATE tor=values(tor),direction=values(direction),tenant=values(tenant),category=values(category),account=values(account),subject=values(subject),destination=values(destination),cost=values(cost),timespans=values(timespans),cost_source=values(cost_source),updated_at='%s'", - utils.TBL_COST_DETAILS, - cgrid, - runid, - cc.TOR, - cc.Direction, - cc.Tenant, - cc.Category, - cc.Account, - cc.Subject, - cc.Destination, - cc.Cost, - tss, - source, - time.Now().Format(time.RFC3339), - time.Now().Format(time.RFC3339))) - if err != nil { - utils.Logger.Err(fmt.Sprintf("failed to execute insert statement: %v", err)) - return err - } - return nil -} - -func (self *MySQLStorage) SetRatedCdr(storedCdr *StoredCdr) (err error) { - _, err = self.Db.Exec(fmt.Sprintf("INSERT INTO %s (cgrid,runid,reqtype,direction,tenant,category,account,subject,destination,setup_time,answer_time,`usage`,pdd,supplier,disconnect_cause,cost,extra_info,created_at) VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%v,%v,'%s','%s',%f,'%s','%s') ON DUPLICATE KEY UPDATE reqtype=values(reqtype),direction=values(direction),tenant=values(tenant),category=values(category),account=values(account),subject=values(subject),destination=values(destination),setup_time=values(setup_time),answer_time=values(answer_time),`usage`=values(`usage`),pdd=values(pdd),cost=values(cost),supplier=values(supplier),disconnect_cause=values(disconnect_cause),extra_info=values(extra_info), updated_at='%s'", - utils.TBL_RATED_CDRS, - storedCdr.CgrId, - storedCdr.MediationRunId, - storedCdr.ReqType, - storedCdr.Direction, - storedCdr.Tenant, - storedCdr.Category, - storedCdr.Account, - storedCdr.Subject, - storedCdr.Destination, - storedCdr.SetupTime, - storedCdr.AnswerTime, - storedCdr.Usage.Seconds(), - storedCdr.Pdd.Seconds(), - storedCdr.Supplier, - storedCdr.DisconnectCause, - storedCdr.Cost, - storedCdr.ExtraInfo, - time.Now().Format(time.RFC3339), - time.Now().Format(time.RFC3339))) - if err != nil { - utils.Logger.Err(fmt.Sprintf("failed to execute cdr insert statement: %s", err.Error())) - } - return -} diff --git a/engine/storage_mysql_local_test.go b/engine/storage_mysql_local_test.go index d8a35e1d1..070c83127 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -48,10 +48,8 @@ func TestMySQLCreateTables(t *testing.T) { return // No point in going further } } - for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { - if _, err := mysqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil { - t.Error(err.Error()) - } + if _, err := mysqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", utils.TBL_CDRS)); err != nil { + t.Error(err.Error()) } } diff --git a/engine/storage_postgres.go b/engine/storage_postgres.go index 8641e828b..00862cd39 100644 --- a/engine/storage_postgres.go +++ b/engine/storage_postgres.go @@ -19,12 +19,7 @@ along with this program. If not, see package engine import ( - "encoding/json" "fmt" - "path" - "time" - - "github.com/cgrates/cgrates/utils" "github.com/jinzhu/gorm" _ "github.com/lib/pq" @@ -50,97 +45,3 @@ func NewPostgresStorage(host, port, name, user, password string, maxConn, maxIdl return &PostgresStorage{&SQLStorage{Db: db.DB(), db: db}}, nil } - -func (self *PostgresStorage) Flush(scriptsPath string) (err error) { - for _, scriptName := range []string{utils.CREATE_CDRS_TABLES_SQL, utils.CREATE_TARIFFPLAN_TABLES_SQL} { - if err := self.CreateTablesFromScript(path.Join(scriptsPath, scriptName)); err != nil { - return err - } - } - for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { - if _, err := self.Db.Query(fmt.Sprintf("SELECT 1 FROM %s", tbl)); err != nil { - return err - } - } - return nil -} - -func (self *PostgresStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) (err error) { - if cc == nil { - return nil - } - tss, err := json.Marshal(cc.Timespans) - if err != nil { - utils.Logger.Err(fmt.Sprintf("Error marshalling timespans to json: %v", err)) - return err - } - tx := self.db.Begin() - cd := &TblCostDetail{ - Cgrid: cgrid, - Runid: runid, - Tor: cc.TOR, - Direction: cc.Direction, - Tenant: cc.Tenant, - Category: cc.Category, - Account: cc.Account, - Subject: cc.Subject, - Destination: cc.Destination, - Cost: cc.Cost, - Timespans: string(tss), - CostSource: source, - CreatedAt: time.Now(), - } - - if tx.Save(cd).Error != nil { // Check further since error does not properly reflect duplicates here (sql: no rows in result set) - tx.Rollback() - tx = self.db.Begin() - updated := tx.Model(TblCostDetail{}).Where(&TblCostDetail{Cgrid: cgrid, Runid: runid}).Updates(&TblCostDetail{Tor: cc.TOR, Direction: cc.Direction, Tenant: cc.Tenant, Category: cc.Category, - Account: cc.Account, Subject: cc.Subject, Destination: cc.Destination, Cost: cc.Cost, Timespans: string(tss), CostSource: source, UpdatedAt: time.Now()}) - if updated.Error != nil { - tx.Rollback() - return updated.Error - } - } - tx.Commit() - return nil -} - -func (self *PostgresStorage) SetRatedCdr(cdr *StoredCdr) (err error) { - tx := self.db.Begin() - saved := tx.Save(&TblRatedCdr{ - Cgrid: cdr.CgrId, - Runid: cdr.MediationRunId, - Reqtype: cdr.ReqType, - Direction: cdr.Direction, - Tenant: cdr.Tenant, - Category: cdr.Category, - Account: cdr.Account, - Subject: cdr.Subject, - Destination: cdr.Destination, - SetupTime: cdr.SetupTime, - AnswerTime: cdr.AnswerTime, - Usage: cdr.Usage.Seconds(), - Pdd: cdr.Pdd.Seconds(), - Supplier: cdr.Supplier, - DisconnectCause: cdr.DisconnectCause, - Cost: cdr.Cost, - ExtraInfo: cdr.ExtraInfo, - CreatedAt: time.Now(), - }) - if saved.Error != nil { - tx.Rollback() - tx = self.db.Begin() - updated := tx.Model(TblRatedCdr{}).Where(&TblRatedCdr{Cgrid: cdr.CgrId, Runid: cdr.MediationRunId}).Updates(&TblRatedCdr{Reqtype: cdr.ReqType, - Direction: cdr.Direction, Tenant: cdr.Tenant, Category: cdr.Category, Account: cdr.Account, Subject: cdr.Subject, Destination: cdr.Destination, - SetupTime: cdr.SetupTime, AnswerTime: cdr.AnswerTime, Usage: cdr.Usage.Seconds(), Pdd: cdr.Pdd.Seconds(), Supplier: cdr.Supplier, DisconnectCause: cdr.DisconnectCause, - Cost: cdr.Cost, ExtraInfo: cdr.ExtraInfo, - UpdatedAt: time.Now()}) - if updated.Error != nil { - tx.Rollback() - return updated.Error - } - } - tx.Commit() - return nil - -} diff --git a/engine/storage_psql_local_test.go b/engine/storage_psql_local_test.go index f1743cc12..00b917cdf 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -48,10 +48,8 @@ func TestPSQLCreateTables(t *testing.T) { return // No point in going further } } - for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { - if _, err := psqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil { - t.Error(err.Error()) - } + if _, err := psqlDb.Db.Query(fmt.Sprintf("SELECT 1 from %s", utils.TBL_CDRS)); err != nil { + t.Error(err.Error()) } } diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 9e550d066..4d128079b 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -24,6 +24,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "path" "strconv" "strings" "time" @@ -43,8 +44,16 @@ func (self *SQLStorage) Close() { self.db.Close() } -func (self *SQLStorage) Flush(placeholder string) (err error) { - return utils.ErrNotImplemented +func (self *SQLStorage) Flush(scriptsPath string) (err error) { + for _, scriptName := range []string{utils.CREATE_CDRS_TABLES_SQL, utils.CREATE_TARIFFPLAN_TABLES_SQL} { + if err := self.CreateTablesFromScript(path.Join(scriptsPath, scriptName)); err != nil { + return err + } + } + if _, err := self.Db.Query(fmt.Sprintf("SELECT 1 FROM %s", utils.TBL_CDRS)); err != nil { + return err + } + return nil } func (self *SQLStorage) GetKeysForPrefix(prefix string) ([]string, error) { @@ -561,14 +570,49 @@ func (self *SQLStorage) SetTpAccountActions(aas []TpAccountAction) error { return nil } +func (self *SQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) (err error) { + if cc == nil { + return nil + } + tss, err := json.Marshal(cc.Timespans) + if err != nil { + utils.Logger.Err(fmt.Sprintf("Error marshalling timespans to json: %v", err)) + return err + } + tx := self.db.Begin() + cd := &TblCdrs{ + Cgrid: cgrid, + Runid: runid, + Tor: cc.TOR, + Direction: cc.Direction, + Tenant: cc.Tenant, + Category: cc.Category, + Account: cc.Account, + Subject: cc.Subject, + Destination: cc.Destination, + Cost: cc.Cost, + Timespans: string(tss), + CostSource: source, + CreatedAt: time.Now(), + } -func (self *SQLStorage) LogCallCost(cgrid, source, runid string, cc *CallCost) error { - return utils.ErrNotImplemented + if tx.Save(cd).Error != nil { // Check further since error does not properly reflect duplicates here (sql: no rows in result set) + tx.Rollback() + tx = self.db.Begin() + updated := tx.Model(TblCdrs{}).Where(&TblCdrs{Cgrid: cgrid, Runid: runid}).Updates(&TblCdrs{Tor: cc.TOR, Direction: cc.Direction, Tenant: cc.Tenant, Category: cc.Category, + Account: cc.Account, Subject: cc.Subject, Destination: cc.Destination, Cost: cc.Cost, Timespans: string(tss), CostSource: source, UpdatedAt: time.Now()}) + if updated.Error != nil { + tx.Rollback() + return updated.Error + } + } + tx.Commit() + return nil } func (self *SQLStorage) GetCallCostLog(cgrid, source, runid string) (*CallCost, error) { - var tpCostDetail TblCostDetail - if err := self.db.Where(&TblCostDetail{Cgrid: cgrid, Runid: runid, CostSource: source}).First(&tpCostDetail).Error; err != nil { + var tpCostDetail TblCdrs + if err := self.db.Where(&TblCdrs{Cgrid: cgrid, Runid: runid, CostSource: source}).First(&tpCostDetail).Error; err != nil { return nil, err } if len(tpCostDetail.Timespans) == 0 { @@ -602,7 +646,7 @@ func (self *SQLStorage) SetCdr(cdr *StoredCdr) error { return err } tx := self.db.Begin() - saved := tx.Save(&TblCdrsPrimary{ + saved := tx.Save(&TblCdrs{ Cgrid: cdr.CgrId, Tor: cdr.TOR, Accid: cdr.AccId, @@ -621,243 +665,184 @@ func (self *SQLStorage) SetCdr(cdr *StoredCdr) error { Pdd: cdr.Pdd.Seconds(), Supplier: cdr.Supplier, DisconnectCause: cdr.DisconnectCause, + ExtraFields: string(extraFields), CreatedAt: time.Now()}) if saved.Error != nil { tx.Rollback() return saved.Error } - // Save extra fields - if err := tx.Save(&TblCdrsExtra{Cgrid: cdr.CgrId, ExtraFields: string(extraFields), CreatedAt: time.Now()}).Error; err != nil { - tx.Rollback() - return err - } tx.Commit() return nil } -func (self *SQLStorage) SetRatedCdr(storedCdr *StoredCdr) error { - return utils.ErrNotImplemented +func (self *SQLStorage) SetRatedCdr(cdr *StoredCdr) (err error) { + tx := self.db.Begin() + saved := tx.Save(&TblCdrs{ + Cgrid: cdr.CgrId, + Runid: cdr.MediationRunId, + Reqtype: cdr.ReqType, + Direction: cdr.Direction, + Tenant: cdr.Tenant, + Category: cdr.Category, + Account: cdr.Account, + Subject: cdr.Subject, + Destination: cdr.Destination, + SetupTime: cdr.SetupTime, + AnswerTime: cdr.AnswerTime, + Usage: cdr.Usage.Seconds(), + Pdd: cdr.Pdd.Seconds(), + Supplier: cdr.Supplier, + DisconnectCause: cdr.DisconnectCause, + Cost: cdr.Cost, + ExtraInfo: cdr.ExtraInfo, + CreatedAt: time.Now(), + }) + if saved.Error != nil { + tx.Rollback() + tx = self.db.Begin() + updated := tx.Model(TblCdrs{}).Where(&TblCdrs{Cgrid: cdr.CgrId, Runid: cdr.MediationRunId}).Updates(&TblCdrs{Reqtype: cdr.ReqType, + Direction: cdr.Direction, Tenant: cdr.Tenant, Category: cdr.Category, Account: cdr.Account, Subject: cdr.Subject, Destination: cdr.Destination, + SetupTime: cdr.SetupTime, AnswerTime: cdr.AnswerTime, Usage: cdr.Usage.Seconds(), Pdd: cdr.Pdd.Seconds(), Supplier: cdr.Supplier, DisconnectCause: cdr.DisconnectCause, + Cost: cdr.Cost, ExtraInfo: cdr.ExtraInfo, + UpdatedAt: time.Now()}) + if updated.Error != nil { + tx.Rollback() + return updated.Error + } + } + tx.Commit() + return nil + } + func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*StoredCdr, int64, error) { var cdrs []*StoredCdr - // Select string - var selectStr string - if qryFltr.FilterOnRated { // We use different tables to query account data in case of derived - selectStr = fmt.Sprintf("%s.cgrid,%s.id,%s.tor,%s.accid,%s.cdrhost,%s.cdrsource,%s.reqtype,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.setup_time,%s.answer_time,%s.usage,%s.pdd,%s.supplier,%s.disconnect_cause,%s.extra_fields,%s.runid,%s.cost,%s.tor,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.cost,%s.timespans", - utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, - utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, - utils.TBL_CDRS_EXTRA, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, - utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS) - } else { - selectStr = fmt.Sprintf("%s.cgrid,%s.id,%s.tor,%s.accid,%s.cdrhost,%s.cdrsource,%s.reqtype,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.setup_time,%s.answer_time,%s.usage,%s.pdd,%s.supplier,%s.disconnect_cause,%s.extra_fields,%s.runid,%s.cost,%s.tor,%s.direction,%s.tenant,%s.category,%s.account,%s.subject,%s.destination,%s.cost,%s.timespans", - utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, - utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_PRIMARY, - utils.TBL_CDRS_EXTRA, utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, - utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS, utils.TBL_COST_DETAILS) - } - // 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) - q := self.db.Table(utils.TBL_CDRS_PRIMARY).Select(selectStr).Joins(joinStr) + q := self.db.Table(utils.TBL_CDRS).Select("*") if qryFltr.Unscoped { q = q.Unscoped() } else { // Query filter - for _, tblName := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA, utils.TBL_COST_DETAILS, utils.TBL_RATED_CDRS} { - q = q.Where(fmt.Sprintf("(%s.deleted_at IS NULL OR %s.deleted_at <= '0001-01-02')", tblName, tblName)) // Soft deletes - } + q = q.Where("(deleted_at IS NULL OR deleted_at <= '0001-01-02')") // Soft deletes } // Add filters, use in to replace the high number of ORs if len(qryFltr.CgrIds) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid in (?)", qryFltr.CgrIds) + q = q.Where("cgrid in (?)", qryFltr.CgrIds) } if len(qryFltr.NotCgrIds) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid not in (?)", qryFltr.NotCgrIds) + q = q.Where("cgrid not in (?)", qryFltr.NotCgrIds) } if len(qryFltr.RunIds) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".runid in (?)", qryFltr.RunIds) + q = q.Where("runid in (?)", qryFltr.RunIds) } if len(qryFltr.NotRunIds) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".runid not in (?)", qryFltr.NotRunIds) + q = q.Where("runid not in (?)", qryFltr.NotRunIds) } if len(qryFltr.Tors) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tor in (?)", qryFltr.Tors) + q = q.Where("tor in (?)", qryFltr.Tors) } if len(qryFltr.NotTors) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tor not in (?)", qryFltr.NotTors) + q = q.Where("tor not in (?)", qryFltr.NotTors) } if len(qryFltr.CdrHosts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost in (?)", qryFltr.CdrHosts) + q = q.Where("cdrhost in (?)", qryFltr.CdrHosts) } if len(qryFltr.NotCdrHosts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost not in (?)", qryFltr.NotCdrHosts) + q = q.Where("cdrhost not in (?)", qryFltr.NotCdrHosts) } if len(qryFltr.CdrSources) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource in (?)", qryFltr.CdrSources) + q = q.Where("cdrsource in (?)", qryFltr.CdrSources) } if len(qryFltr.NotCdrSources) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource not in (?)", qryFltr.NotCdrSources) + q = q.Where("cdrsource not in (?)", qryFltr.NotCdrSources) } if len(qryFltr.ReqTypes) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".reqtype in (?)", qryFltr.ReqTypes) + q = q.Where("reqtype in (?)", qryFltr.ReqTypes) } if len(qryFltr.NotReqTypes) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".reqtype not in (?)", qryFltr.NotReqTypes) + q = q.Where("reqtype not in (?)", qryFltr.NotReqTypes) } if len(qryFltr.Directions) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".direction in (?)", qryFltr.Directions) + q = q.Where("direction in (?)", qryFltr.Directions) } if len(qryFltr.NotDirections) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".direction not in (?)", qryFltr.NotDirections) + q = q.Where("direction not in (?)", qryFltr.NotDirections) } if len(qryFltr.Tenants) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".tenant in (?)", qryFltr.Tenants) + q = q.Where("tenant in (?)", qryFltr.Tenants) } if len(qryFltr.NotTenants) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".tenant not in (?)", qryFltr.NotTenants) + q = q.Where("tenant not in (?)", qryFltr.NotTenants) } if len(qryFltr.Categories) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".category in (?)", qryFltr.Categories) + q = q.Where("category in (?)", qryFltr.Categories) } if len(qryFltr.NotCategories) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".category not in (?)", qryFltr.NotCategories) + q = q.Where("category not in (?)", qryFltr.NotCategories) } if len(qryFltr.Accounts) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".account in (?)", qryFltr.Accounts) + q = q.Where("account in (?)", qryFltr.Accounts) } if len(qryFltr.NotAccounts) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".account not in (?)", qryFltr.NotAccounts) + q = q.Where("account not in (?)", qryFltr.NotAccounts) } if len(qryFltr.Subjects) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".subject in (?)", qryFltr.Subjects) + q = q.Where("subject in (?)", qryFltr.Subjects) } if len(qryFltr.NotSubjects) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".subject not in (?)", qryFltr.NotSubjects) + q = q.Where("subject not in (?)", qryFltr.NotSubjects) } if len(qryFltr.DestPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } qIds := bytes.NewBufferString("(") for idx, destPrefix := range qryFltr.DestPrefixes { if idx != 0 { qIds.WriteString(" OR") } - qIds.WriteString(fmt.Sprintf(" %s.destination LIKE '%s%%'", tblName, destPrefix)) + qIds.WriteString(fmt.Sprintf(" destination LIKE '%s%%'", destPrefix)) } qIds.WriteString(" )") q = q.Where(qIds.String()) } if len(qryFltr.NotDestPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } qIds := bytes.NewBufferString("(") for idx, destPrefix := range qryFltr.NotDestPrefixes { if idx != 0 { qIds.WriteString(" AND") } - qIds.WriteString(fmt.Sprintf(" %s.destination not LIKE '%%%s%%'", tblName, destPrefix)) + qIds.WriteString(fmt.Sprintf(" destination not LIKE '%%%s%%'", destPrefix)) } qIds.WriteString(" )") q = q.Where(qIds.String()) } if len(qryFltr.Suppliers) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".supplier in (?)", qryFltr.Subjects) + q = q.Where("supplier in (?)", qryFltr.Subjects) } if len(qryFltr.NotSuppliers) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".supplier not in (?)", qryFltr.NotSubjects) + q = q.Where("supplier not in (?)", qryFltr.NotSubjects) } if len(qryFltr.DisconnectCauses) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".disconnect_cause in (?)", qryFltr.DisconnectCauses) + q = q.Where("disconnect_cause in (?)", qryFltr.DisconnectCauses) } if len(qryFltr.NotDisconnectCauses) != 0 { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".disconnect_cause not in (?)", qryFltr.NotDisconnectCauses) + q = q.Where("disconnect_cause not in (?)", qryFltr.NotDisconnectCauses) } if len(qryFltr.RatedAccounts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".account in (?)", qryFltr.RatedAccounts) + q = q.Where(utils.TBL_CDRS+".account in (?)", qryFltr.RatedAccounts) } if len(qryFltr.NotRatedAccounts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".account not in (?)", qryFltr.NotRatedAccounts) + q = q.Where(utils.TBL_CDRS+".account not in (?)", qryFltr.NotRatedAccounts) } if len(qryFltr.RatedSubjects) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".subject in (?)", qryFltr.RatedSubjects) + q = q.Where(utils.TBL_CDRS+".subject in (?)", qryFltr.RatedSubjects) } if len(qryFltr.NotRatedSubjects) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".subject not in (?)", qryFltr.NotRatedSubjects) + q = q.Where(utils.TBL_CDRS+".subject not in (?)", qryFltr.NotRatedSubjects) } if len(qryFltr.Costs) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".cost in (?)", qryFltr.Costs) + q = q.Where(utils.TBL_CDRS+".cost in (?)", qryFltr.Costs) } if len(qryFltr.NotCosts) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".cost not in (?)", qryFltr.NotCosts) + q = q.Where(utils.TBL_CDRS+".cost not in (?)", qryFltr.NotCosts) } if len(qryFltr.ExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field qIds := bytes.NewBufferString("(") @@ -866,7 +851,7 @@ func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*StoredCdr, if needOr { qIds.WriteString(" OR") } - qIds.WriteString(fmt.Sprintf(` %s.extra_fields LIKE '%%"%s":"%s"%%'`, utils.TBL_CDRS_EXTRA, field, value)) + qIds.WriteString(fmt.Sprintf(` extra_fields LIKE '%%"%s":"%s"%%'`, field, value)) needOr = true } qIds.WriteString(" )") @@ -879,117 +864,69 @@ func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*StoredCdr, if needAnd { qIds.WriteString(" OR") } - qIds.WriteString(fmt.Sprintf(` %s.extra_fields LIKE '%%"%s":"%s"%%'`, utils.TBL_CDRS_EXTRA, field, value)) + qIds.WriteString(fmt.Sprintf(` extra_fields LIKE '%%"%s":"%s"%%'`, field, value)) needAnd = true } qIds.WriteString(" )") q = q.Where(qIds.String()) } if qryFltr.OrderIdStart != 0 { // Keep backwards compatible by testing 0 value - q = q.Where(utils.TBL_CDRS_PRIMARY+".id >= ?", qryFltr.OrderIdStart) + q = q.Where(utils.TBL_CDRS+".id >= ?", qryFltr.OrderIdStart) } if qryFltr.OrderIdEnd != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".id < ?", qryFltr.OrderIdEnd) + q = q.Where(utils.TBL_CDRS+".id < ?", qryFltr.OrderIdEnd) } if qryFltr.SetupTimeStart != nil { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".setup_time >= ?", qryFltr.SetupTimeStart) + q = q.Where("setup_time >= ?", qryFltr.SetupTimeStart) } if qryFltr.SetupTimeEnd != nil { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".setup_time < ?", qryFltr.SetupTimeEnd) + q = q.Where("setup_time < ?", qryFltr.SetupTimeEnd) } if qryFltr.AnswerTimeStart != nil && !qryFltr.AnswerTimeStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".answer_time >= ?", qryFltr.AnswerTimeStart) + q = q.Where("answer_time >= ?", qryFltr.AnswerTimeStart) } if qryFltr.AnswerTimeEnd != nil && !qryFltr.AnswerTimeEnd.IsZero() { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".answer_time < ?", qryFltr.AnswerTimeEnd) + q = q.Where("answer_time < ?", qryFltr.AnswerTimeEnd) } if qryFltr.CreatedAtStart != nil && !qryFltr.CreatedAtStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".created_at >= ?", qryFltr.CreatedAtStart) + q = q.Where("created_at >= ?", qryFltr.CreatedAtStart) } if qryFltr.CreatedAtEnd != nil && !qryFltr.CreatedAtEnd.IsZero() { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".created_at < ?", qryFltr.CreatedAtEnd) + q = q.Where("created_at < ?", qryFltr.CreatedAtEnd) } if qryFltr.UpdatedAtStart != nil && !qryFltr.UpdatedAtStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".updated_at >= ?", qryFltr.UpdatedAtStart) + q = q.Where("updated_at >= ?", qryFltr.UpdatedAtStart) } if qryFltr.UpdatedAtEnd != nil && !qryFltr.UpdatedAtEnd.IsZero() { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".updated_at < ?", qryFltr.UpdatedAtEnd) + q = q.Where("updated_at < ?", qryFltr.UpdatedAtEnd) } if qryFltr.MinUsage != nil { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".usage >= ?", qryFltr.MinUsage) + q = q.Where("usage >= ?", qryFltr.MinUsage) } if qryFltr.MaxUsage != nil { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".usage < ?", qryFltr.MaxUsage) + q = q.Where("usage < ?", qryFltr.MaxUsage) } if qryFltr.MinPdd != nil { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".pdd >= ?", qryFltr.MinPdd) + q = q.Where("pdd >= ?", qryFltr.MinPdd) } if qryFltr.MaxPdd != nil { - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - q = q.Where(tblName+".pdd < ?", qryFltr.MaxPdd) + q = q.Where("pdd < ?", qryFltr.MaxPdd) } if qryFltr.MinCost != nil { if qryFltr.MaxCost == nil { - q = q.Where(utils.TBL_RATED_CDRS+".cost >= ?", *qryFltr.MinCost) + q = q.Where("cost >= ?", *qryFltr.MinCost) } else if *qryFltr.MinCost == 0.0 && *qryFltr.MaxCost == -1.0 { // Special case when we want to skip errors - q = q.Where(fmt.Sprintf("( %s.cost IS NULL OR %s.cost >= 0.0 )", utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS)) + q = q.Where("( cost IS NULL OR cost >= 0.0 )") } else { - q = q.Where(utils.TBL_RATED_CDRS+".cost >= ?", *qryFltr.MinCost) - q = q.Where(utils.TBL_RATED_CDRS+".cost < ?", *qryFltr.MaxCost) + q = q.Where("cost >= ?", *qryFltr.MinCost) + q = q.Where("cost < ?", *qryFltr.MaxCost) } } else if qryFltr.MaxCost != nil { if *qryFltr.MaxCost == -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 + q = q.Where("cost IS NULL") // Need to include it otherwise all CDRs will be returned } else { // Above limited CDRs, since MinCost 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, *qryFltr.MaxCost)) + q = q.Where(fmt.Sprintf("( cost IS NULL OR cost < %f )", *qryFltr.MaxCost)) } } if qryFltr.Paginator.Limit != nil { @@ -1057,353 +994,25 @@ func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*StoredCdr, return cdrs, 0, nil } -/*func (self *SQLStorage) GetStoredCdrs(qryFltr *utils.CdrsFilter) ([]*StoredCdr, int64, error) { - var cdrs []*StoredCdr - // Select string - var selectStr string - if qryFltr.FilterOnRated { // We use different tables to query account data in case of derived - selectTmpl := template.Must(template.New("select").Parse("{{.Pr}}.cgrid,{{.Pr}}.id,{{.Pr}}.tor,{{.Pr}}.accid,{{.Pr}}.cdrhost,{{.Pr}}.cdrsource,{{.Rc}}.reqtype,{{.Rc}}.direction,{{.Rc}}.tenant,{{.Rc}}.category,{{.Rc}}.account,{{.Rc}}.subject,{{.Rc}}.destination,{{.Rc}}.setup_time,{{.Rc}}.answer_time,{{.Rc}}.usage,{{.Rc}}.pdd,{{.Rc}}.supplier,{{.Rc}}.disconnect_cause,{{.Ex}}.extra_fields,{{.Rc}}.runid,{{.Rc}}.cost,{{.Cd}}.tor,{{.Cd}}.direction,{{.Cd}}.tenant,{{.Cd}}.category,{{.Cd}}.account,{{.Cd}}.subject,{{.Cd}}.destination,{{.Cd}}.cost,{{.Cd}}.timespans")) - var selectBuf bytes.Buffer - selectTmpl.Execute(&selectBuf, &struct { - Pr string - Ex string - Rc string - Cd string - }{utils.TBL_CDRS_PRIMARY, - utils.TBL_CDRS_EXTRA, - utils.TBL_RATED_CDRS, - utils.TBL_COST_DETAILS}) - selectStr = selectBuf.String() - } else { - selectTmpl := template.Must(template.New("select").Parse("{{.Pr}}.cgrid,{{.Pr}}.id,{{.Pr}}.tor,{{.Pr}}.accid,{{.Pr}}.cdrhost,{{.Pr}}.cdrsource,{{.Pr}}.reqtype,{{.Pr}}.direction,{{.Pr}}.tenant,{{.Pr}}.category,{{.Pr}}.account,{{.Pr}}.subject,{{.Pr}}.destination,{{.Pr}}.setup_time,{{.Pr}}.answer_time,{{.Pr}}.usage,{{.Pr}}.pdd,{{.Pr}}.supplier,{{.Pr}}.disconnect_cause,{{.Ex}}.extra_fields,{{.Rc}}.runid,{{.Rc}}.cost,{{.Cd}}.tor,{{.Cd}}.direction,{{.Cd}}.tenant,{{.Cd}}.category,{{.Cd}}.account,{{.Cd}}.subject,{{.Cd}}.destination,{{.Cd}}.cost,{{.Cd}}.timespans")) - var selectBuf bytes.Buffer - selectTmpl.Execute(&selectBuf, &struct { - Pr string - Ex string - Rc string - Cd string - }{utils.TBL_CDRS_PRIMARY, - utils.TBL_CDRS_EXTRA, - utils.TBL_RATED_CDRS, - utils.TBL_COST_DETAILS}) - selectStr = selectBuf.String() - } - // Join string - selectTmpl := template.Must(template.New("join").Parse("LEFT JOIN {{.Ex}} ON {{.Pr}}.cgrid={{.Ex}}.cgrid LEFT JOIN {{.Rc}} ON {{.Pr}}.cgrid={{.Rc}}.cgrid LEFT JOIN {{.Cd}} ON {{.Rc}}.cgrid={{.Cd}}.cgrid AND {{.Rc}}.runid={{.Cd}}.runid")) - var joinBuf bytes.Buffer - selectTmpl.Execute(&joinBuf, &struct { - Pr string - Ex string - Rc string - Cd string - }{utils.TBL_CDRS_PRIMARY, - utils.TBL_CDRS_EXTRA, - utils.TBL_RATED_CDRS, - utils.TBL_COST_DETAILS}) - joinStr := joinBuf.String() - q := self.db.Table(utils.TBL_CDRS_PRIMARY).Select(selectStr).Joins(joinStr) - if qryFltr.Unscoped { - q = q.Unscoped() - } else { - // Query filter - for _, tblName := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA, utils.TBL_COST_DETAILS, utils.TBL_RATED_CDRS} { - q = q.Where(fmt.Sprintf("(%s.deleted_at IS NULL OR %s.deleted_at <= '0001-01-02')", tblName, tblName)) // Soft deletes - } - } - tblName := utils.TBL_CDRS_PRIMARY - if qryFltr.FilterOnRated { - tblName = utils.TBL_RATED_CDRS - } - // Add filters, use in to replace the high number of ORs - if len(qryFltr.CgrIds) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid in (?)", qryFltr.CgrIds) - } - if len(qryFltr.NotCgrIds) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cgrid not in (?)", qryFltr.NotCgrIds) - } - if len(qryFltr.RunIds) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".runid in (?)", qryFltr.RunIds) - } - if len(qryFltr.NotRunIds) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".runid not in (?)", qryFltr.NotRunIds) - } - if len(qryFltr.Tors) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tor in (?)", qryFltr.Tors) - } - if len(qryFltr.NotTors) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".tor not in (?)", qryFltr.NotTors) - } - if len(qryFltr.CdrHosts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost in (?)", qryFltr.CdrHosts) - } - if len(qryFltr.NotCdrHosts) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrhost not in (?)", qryFltr.NotCdrHosts) - } - if len(qryFltr.CdrSources) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource in (?)", qryFltr.CdrSources) - } - if len(qryFltr.NotCdrSources) != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".cdrsource not in (?)", qryFltr.NotCdrSources) - } - if len(qryFltr.ReqTypes) != 0 { - q = q.Where(tblName+".reqtype in (?)", qryFltr.ReqTypes) - } - if len(qryFltr.NotReqTypes) != 0 { - q = q.Where(tblName+".reqtype not in (?)", qryFltr.NotReqTypes) - } - if len(qryFltr.Directions) != 0 { - q = q.Where(tblName+".direction in (?)", qryFltr.Directions) - } - if len(qryFltr.NotDirections) != 0 { - q = q.Where(tblName+".direction not in (?)", qryFltr.NotDirections) - } - if len(qryFltr.Tenants) != 0 { - q = q.Where(tblName+".tenant in (?)", qryFltr.Tenants) - } - if len(qryFltr.NotTenants) != 0 { - q = q.Where(tblName+".tenant not in (?)", qryFltr.NotTenants) - } - if len(qryFltr.Categories) != 0 { - q = q.Where(tblName+".category in (?)", qryFltr.Categories) - } - if len(qryFltr.NotCategories) != 0 { - q = q.Where(tblName+".category not in (?)", qryFltr.NotCategories) - } - if len(qryFltr.Accounts) != 0 { - q = q.Where(tblName+".account in (?)", qryFltr.Accounts) - } - if len(qryFltr.NotAccounts) != 0 { - q = q.Where(tblName+".account not in (?)", qryFltr.NotAccounts) - } - if len(qryFltr.Subjects) != 0 { - q = q.Where(tblName+".subject in (?)", qryFltr.Subjects) - } - if len(qryFltr.NotSubjects) != 0 { - q = q.Where(tblName+".subject not in (?)", qryFltr.NotSubjects) - } - if len(qryFltr.DestPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm - qIds := bytes.NewBufferString("(") - for idx, destPrefix := range qryFltr.DestPrefixes { - if idx != 0 { - qIds.WriteString(" OR") - } - qIds.WriteString(fmt.Sprintf(" %s.destination LIKE '%s%%'", tblName, destPrefix)) - } - qIds.WriteString(" )") - q = q.Where(qIds.String()) - } - if len(qryFltr.NotDestPrefixes) != 0 { // A bit ugly but still more readable than scopes provided by gorm - qIds := bytes.NewBufferString("(") - for idx, destPrefix := range qryFltr.NotDestPrefixes { - if idx != 0 { - qIds.WriteString(" AND") - } - qIds.WriteString(fmt.Sprintf(" %s.destination not LIKE '%%%s%%'", tblName, destPrefix)) - } - qIds.WriteString(" )") - q = q.Where(qIds.String()) - } - if len(qryFltr.Suppliers) != 0 { - q = q.Where(tblName+".supplier in (?)", qryFltr.Subjects) - } - if len(qryFltr.NotSuppliers) != 0 { - q = q.Where(tblName+".supplier not in (?)", qryFltr.NotSubjects) - } - if len(qryFltr.DisconnectCauses) != 0 { - q = q.Where(tblName+".disconnect_cause in (?)", qryFltr.DisconnectCauses) - } - if len(qryFltr.NotDisconnectCauses) != 0 { - q = q.Where(tblName+".disconnect_cause not in (?)", qryFltr.NotDisconnectCauses) - } - if len(qryFltr.RatedAccounts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".account in (?)", qryFltr.RatedAccounts) - } - if len(qryFltr.NotRatedAccounts) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".account not in (?)", qryFltr.NotRatedAccounts) - } - if len(qryFltr.RatedSubjects) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".subject in (?)", qryFltr.RatedSubjects) - } - if len(qryFltr.NotRatedSubjects) != 0 { - q = q.Where(utils.TBL_COST_DETAILS+".subject not in (?)", qryFltr.NotRatedSubjects) - } - if len(qryFltr.Costs) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".cost in (?)", qryFltr.Costs) - } - if len(qryFltr.NotCosts) != 0 { - q = q.Where(utils.TBL_RATED_CDRS+".cost not in (?)", qryFltr.NotCosts) - } - if len(qryFltr.ExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field - qIds := bytes.NewBufferString("(") - needOr := false - for field, value := range qryFltr.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(qryFltr.NotExtraFields) != 0 { // Extra fields searches, implemented as contains in extra field - qIds := bytes.NewBufferString("(") - needAnd := false - for field, value := range qryFltr.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 qryFltr.OrderIdStart != 0 { // Keep backwards compatible by testing 0 value - q = q.Where(utils.TBL_CDRS_PRIMARY+".id >= ?", qryFltr.OrderIdStart) - } - if qryFltr.OrderIdEnd != 0 { - q = q.Where(utils.TBL_CDRS_PRIMARY+".id < ?", qryFltr.OrderIdEnd) - } - if qryFltr.SetupTimeStart != nil { - q = q.Where(tblName+".setup_time >= ?", qryFltr.SetupTimeStart) - } - if qryFltr.SetupTimeEnd != nil { - q = q.Where(tblName+".setup_time < ?", qryFltr.SetupTimeEnd) - } - if qryFltr.AnswerTimeStart != nil && !qryFltr.AnswerTimeStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - q = q.Where(tblName+".answer_time >= ?", qryFltr.AnswerTimeStart) - } - if qryFltr.AnswerTimeEnd != nil && !qryFltr.AnswerTimeEnd.IsZero() { - q = q.Where(tblName+".answer_time < ?", qryFltr.AnswerTimeEnd) - } - if qryFltr.CreatedAtStart != nil && !qryFltr.CreatedAtStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - q = q.Where(tblName+".created_at >= ?", qryFltr.CreatedAtStart) - } - if qryFltr.CreatedAtEnd != nil && !qryFltr.CreatedAtEnd.IsZero() { - q = q.Where(tblName+".created_at < ?", qryFltr.CreatedAtEnd) - } - if qryFltr.UpdatedAtStart != nil && !qryFltr.UpdatedAtStart.IsZero() { // With IsZero we keep backwards compatible with ApierV1 - q = q.Where(tblName+".updated_at >= ?", qryFltr.UpdatedAtStart) - } - if qryFltr.UpdatedAtEnd != nil && !qryFltr.UpdatedAtEnd.IsZero() { - q = q.Where(tblName+".updated_at < ?", qryFltr.UpdatedAtEnd) - } - if qryFltr.MinUsage != nil { - q = q.Where(tblName+".usage >= ?", qryFltr.MinUsage) - } - if qryFltr.MaxUsage != nil { - q = q.Where(tblName+".usage < ?", qryFltr.MaxUsage) - } - if qryFltr.MinPdd != nil { - q = q.Where(tblName+".pdd >= ?", qryFltr.MinPdd) - } - if qryFltr.MaxPdd != nil { - q = q.Where(tblName+".pdd < ?", qryFltr.MaxPdd) - } - - if qryFltr.MinCost != nil { - if qryFltr.MaxCost == nil { - q = q.Where(utils.TBL_RATED_CDRS+".cost >= ?", *qryFltr.MinCost) - } else if *qryFltr.MinCost == 0.0 && *qryFltr.MaxCost == -1.0 { // Special case when we want to skip errors - q = q.Where(fmt.Sprintf("( %s.cost IS NULL OR %s.cost >= 0.0 )", utils.TBL_RATED_CDRS, utils.TBL_RATED_CDRS)) - } else { - q = q.Where(utils.TBL_RATED_CDRS+".cost >= ?", *qryFltr.MinCost) - q = q.Where(utils.TBL_RATED_CDRS+".cost < ?", *qryFltr.MaxCost) - } - } else if qryFltr.MaxCost != nil { - if *qryFltr.MaxCost == -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 MinCost 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, *qryFltr.MaxCost)) - } - } - if qryFltr.Paginator.Limit != nil { - q = q.Limit(*qryFltr.Paginator.Limit) - } - if qryFltr.Paginator.Offset != nil { - q = q.Offset(*qryFltr.Paginator.Offset) - } - if qryFltr.Count { - var cnt int64 - if err := q.Count(&cnt).Error; err != nil { - //if err := q.Debug().Count(&cnt).Error; err != nil { - return nil, 0, err - } - return nil, cnt, nil - } - - // Execute query - rows, err := q.Rows() - if err != nil { - return nil, 0, err - } - for rows.Next() { - var cgrid, tor, accid, cdrhost, cdrsrc, reqtype, direction, tenant, category, account, subject, destination, runid, ccTor, - ccDirection, ccTenant, ccCategory, ccAccount, ccSubject, ccDestination, ccSupplier, ccDisconnectCause sql.NullString - var extraFields, ccTimespansBytes []byte - var setupTime, answerTime mysql.NullTime - var orderid int64 - var usage, pdd, cost, ccCost sql.NullFloat64 - var extraFieldsMp map[string]string - var ccTimespans TimeSpans - if err := rows.Scan(&cgrid, &orderid, &tor, &accid, &cdrhost, &cdrsrc, &reqtype, &direction, &tenant, &category, &account, &subject, &destination, - &setupTime, &answerTime, &usage, &pdd, &ccSupplier, &ccDisconnectCause, - &extraFields, &runid, &cost, &ccTor, &ccDirection, &ccTenant, &ccCategory, &ccAccount, &ccSubject, &ccDestination, &ccCost, &ccTimespansBytes); err != nil { - return nil, 0, err - } - if len(extraFields) != 0 { - if err := json.Unmarshal(extraFields, &extraFieldsMp); err != nil { - return nil, 0, fmt.Errorf("JSON unmarshal error for cgrid: %s, runid: %v, error: %s", cgrid.String, runid.String, err.Error()) - } - } - if len(ccTimespansBytes) != 0 { - if err := json.Unmarshal(ccTimespansBytes, &ccTimespans); err != nil { - return nil, 0, fmt.Errorf("JSON unmarshal callcost error for cgrid: %s, runid: %v, error: %s", cgrid.String, runid.String, err.Error()) - } - } - usageDur, _ := time.ParseDuration(strconv.FormatFloat(usage.Float64, 'f', -1, 64) + "s") - pddDur, _ := time.ParseDuration(strconv.FormatFloat(pdd.Float64, 'f', -1, 64) + "s") - storCdr := &StoredCdr{ - CgrId: cgrid.String, OrderId: orderid, TOR: tor.String, AccId: accid.String, CdrHost: cdrhost.String, CdrSource: cdrsrc.String, ReqType: reqtype.String, - Direction: direction.String, Tenant: tenant.String, - Category: category.String, Account: account.String, Subject: subject.String, Destination: destination.String, - SetupTime: setupTime.Time, AnswerTime: answerTime.Time, Usage: usageDur, Pdd: pddDur, Supplier: ccSupplier.String, DisconnectCause: ccDisconnectCause.String, - ExtraFields: extraFieldsMp, MediationRunId: runid.String, RatedAccount: ccAccount.String, RatedSubject: ccSubject.String, Cost: cost.Float64, - } - if ccTimespans != nil { - storCdr.CostDetails = &CallCost{Direction: ccDirection.String, Category: ccCategory.String, Tenant: ccTenant.String, Subject: ccSubject.String, Account: ccAccount.String, Destination: ccDestination.String, TOR: ccTor.String, - Cost: ccCost.Float64, Timespans: ccTimespans} - } - if !cost.Valid { //There was no cost provided, will fakely insert 0 if we do not handle it and reflect on re-rating - storCdr.Cost = -1 - } - cdrs = append(cdrs, storCdr) - } - return cdrs, 0, nil -} -*/ - // Remove CDR data out of all CDR tables based on their cgrid func (self *SQLStorage) RemStoredCdrs(cgrIds []string) error { if len(cgrIds) == 0 { return nil } tx := self.db.Begin() - for _, tblName := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA, utils.TBL_COST_DETAILS, utils.TBL_RATED_CDRS} { - txI := tx.Table(tblName) - for idx, cgrId := range cgrIds { - if idx == 0 { - txI = txI.Where("cgrid = ?", cgrId) - } else { - txI = txI.Or("cgrid = ?", cgrId) - } - } - if err := txI.Update("deleted_at", time.Now()).Error; err != nil { - tx.Rollback() - return err + + txI := tx.Table(utils.TBL_CDRS) + for idx, cgrId := range cgrIds { + if idx == 0 { + txI = txI.Where("cgrid = ?", cgrId) + } else { + txI = txI.Or("cgrid = ?", cgrId) } } + if err := txI.Update("deleted_at", time.Now()).Error; err != nil { + tx.Rollback() + return err + } tx.Commit() return nil } diff --git a/general_tests/multiplecdrc_local_test.go b/general_tests/multiplecdrc_local_test.go index f651e2a7c..7efce9392 100644 --- a/general_tests/multiplecdrc_local_test.go +++ b/general_tests/multiplecdrc_local_test.go @@ -92,10 +92,8 @@ func TestEmptyTables(t *testing.T) { t.Fatal("Error on mysql creation: ", err.Error()) return // No point in going further } - for _, tbl := range []string{utils.TBL_CDRS_PRIMARY, utils.TBL_CDRS_EXTRA} { - if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", tbl)); err != nil { - t.Fatal(err.Error()) - } + if _, err := mysql.Db.Query(fmt.Sprintf("SELECT 1 from %s", utils.TBL_CDRS)); err != nil { + t.Fatal(err.Error()) } } diff --git a/utils/consts.go b/utils/consts.go index 3e3b3ad50..f8f9cba3d 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -62,10 +62,7 @@ const ( TBL_TP_DERIVED_CHARGERS = "tp_derived_chargers" TBL_TP_USERS = "tp_users" TBL_TP_ALIASES = "tp_aliases" - TBL_CDRS_PRIMARY = "cdrs_primary" - TBL_CDRS_EXTRA = "cdrs_extra" - TBL_COST_DETAILS = "cost_details" - TBL_RATED_CDRS = "rated_cdrs" + TBL_CDRS = "cdrs" TIMINGS_CSV = "Timings.csv" DESTINATIONS_CSV = "Destinations.csv" RATES_CSV = "Rates.csv"