155 lines
4.4 KiB
Go
155 lines
4.4 KiB
Go
package mongo
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"fiskerinc.com/modules/common"
|
|
"fiskerinc.com/modules/logger"
|
|
"github.com/pkg/errors"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
)
|
|
|
|
type DTCCollectionInterface interface {
|
|
GetDTCDefinitionByHexString(troubleCodeHex string) (info common.DTCInformation, err error)
|
|
GetLatestPDXVersions() (latestVersion PDXVersion, err error)
|
|
}
|
|
|
|
var (
|
|
pdxMongodbOnce sync.Once
|
|
pdxMongodbInstance *DTCCollection
|
|
)
|
|
|
|
type DTCCollection struct {
|
|
CollectionInterface
|
|
Client *mongo.Client
|
|
DB *mongo.Database
|
|
}
|
|
|
|
func GetPDXMongoClient() (*DTCCollection, error) {
|
|
var err error
|
|
pdxMongodbOnce.Do(func() {
|
|
logger.Info().Msg("init MongoDB instance")
|
|
pdxMongodbInstance = &DTCCollection{}
|
|
var cl *mongo.Client
|
|
var db *mongo.Database
|
|
cl, db, err = NewMongoConnection(ODXDB)
|
|
|
|
pdxMongodbInstance.Client = cl
|
|
pdxMongodbInstance.DB = db
|
|
})
|
|
return pdxMongodbInstance, err
|
|
}
|
|
|
|
// Given a Hex String for 3 bytes, get the dtc information from mongo
|
|
func (coll *DTCCollection) GetDTCDefinitionByHexString(troubleCodeHex string, ecuSource string) (info *common.DTCInformation, err error) {
|
|
if replacement, exist := common.CarDTCLookupInverse[ecuSource]; exist {
|
|
ecuSource = replacement
|
|
}
|
|
|
|
collect := coll.DB.Collection("dtc_lookup")
|
|
//db.dtc_lookup.aggregate({"$match": {"ecuName": "ECU", "DtcUniqueId": "V2.6.0"}}, {"$unwind": "$dtcData.DtcList"}, {"$match": {"dtcData.DtcList.TroubleCodeHex":"800156"}}, {"$project":{"_id": 0, "Obj": "$dtcData.DtcList"}})
|
|
pdxVersion, err := coll.GetLatestPDXVersions()
|
|
if err != nil {
|
|
return
|
|
}
|
|
a := bson.D{}
|
|
if ecuSource == "AMP" {
|
|
a = bson.D{{"$match", bson.D{{"ecuName", bson.M{"$in": []string{"AMPSO", "AMPHA"}}}, {"DtcUniqueId", pdxVersion.PDXVersion}}}}
|
|
} else {
|
|
a = bson.D{{"$match", bson.D{{"ecuName", ecuSource}, {"DtcUniqueId", pdxVersion.PDXVersion}}}}
|
|
}
|
|
|
|
b := bson.D{{"$unwind", "$dtcData.DtcList"}}
|
|
c := bson.D{{"$match", bson.D{{"dtcData.DtcList.TroubleCodeHex", troubleCodeHex}}}}
|
|
d := bson.D{{"$project", bson.D{{"_id", 0}, {"Obj", "$dtcData.DtcList"}}}}
|
|
cursor, err := collect.Aggregate(context.Background(), mongo.Pipeline{a, b, c, d})
|
|
if err != nil {
|
|
err = errors.WithStack(err)
|
|
logger.Err(err).Msg("Failed to call aggregate in GetDTCDefinitionByHexString")
|
|
return
|
|
}
|
|
|
|
var obj DTCOuterObj
|
|
for cursor.Next(context.Background()) {
|
|
err = cursor.Decode(&obj)
|
|
if err != nil {
|
|
err = errors.WithStack(err)
|
|
logger.Err(err).Msg("Failed to decode mongo object into DTCInformation")
|
|
return
|
|
}
|
|
info = &obj.DTCInformation
|
|
}
|
|
return
|
|
}
|
|
|
|
// This value should be cached for a period of time
|
|
func (coll *DTCCollection) GetLatestPDXVersions() (latestVersion PDXVersion, err error) {
|
|
//db.vod_lookup.aggregate({"$project": {"VodUniqueId": 1, "createDate": 1, "updateDate": 1}})
|
|
collect := coll.DB.Collection("vod_lookup")
|
|
a := bson.D{{"$project", bson.D{{"VodUniqueId", 1}, {"createDate", 1}, {"updateDate", 1}, {"_id", 0}}}}
|
|
cursor, err := collect.Aggregate(context.Background(), mongo.Pipeline{a})
|
|
if err != nil {
|
|
err = errors.WithStack(err)
|
|
logger.Err(err).Msg("")
|
|
return
|
|
}
|
|
|
|
// Need to determine the latest version
|
|
for cursor.Next(context.Background()) {
|
|
var ag PDXVersion
|
|
err = cursor.Decode(&ag)
|
|
if err != nil {
|
|
err = errors.WithStack(err)
|
|
logger.Err(err).Msg("")
|
|
return
|
|
}
|
|
if isVersionNewer(latestVersion.PDXVersion, ag.PDXVersion) {
|
|
latestVersion = ag
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// Give the one we have as the newest, and then the new value to compare to
|
|
func isVersionNewer(lastNewest, newPossibleNewest string) (isNewer bool) {
|
|
// Better algorithm, turn V1.3.2.1 => 1321 and add any 0's on the end if the other number is longer
|
|
if lastNewest == "" {
|
|
return true
|
|
}
|
|
// Remove the V
|
|
lastNewest = lastNewest[1:]
|
|
newPossibleNewest = newPossibleNewest[1:]
|
|
last := strings.Split(lastNewest, ".")
|
|
new := strings.Split(newPossibleNewest, ".")
|
|
for x := 0; x < len(last); x++ {
|
|
// We have gotten to the end of the second string without being less, so we are greater, like a hotfix
|
|
if x >= len(new) {
|
|
return false
|
|
}
|
|
l, _ := strconv.Atoi(last[x])
|
|
n, _ := strconv.Atoi(new[x])
|
|
|
|
if n > l {
|
|
return true
|
|
} else if l > n {
|
|
return false
|
|
}
|
|
}
|
|
return len(new) > len(last)
|
|
}
|
|
|
|
type DTCOuterObj struct {
|
|
common.DTCInformation `bson:"Obj"`
|
|
}
|
|
|
|
type PDXVersion struct {
|
|
PDXVersion string `bson:"VodUniqueId"`
|
|
CreatedTime time.Time `bson:"createDate"`
|
|
UpdatedTime time.Time `bson:"updateDate"`
|
|
}
|