package dbm import ( "bufio" "encoding/json" "fmt" "os" "strings" "sync" "time" "github.com/tecamino/tecamino-dbm/args" "github.com/tecamino/tecamino-dbm/models" serverModels "github.com/tecamino/tecamino-dbm/server/models" json_dataModels "github.com/tecamino/tecamino-json_data/models" "github.com/tecamino/tecamino-logger/logging" ) type DBMHandler struct { filePath string DB models.Datapoint Conns *serverModels.Connections sync.RWMutex Log *logging.Logger arg *args.Args } // initialze new Database Manager // it will call cli arguments func NewDbmHandler(a *args.Args) (*DBMHandler, error) { logger, err := logging.NewLogger("dbmServer.log", &logging.Config{ MaxSize: 1, MaxBackup: 3, MaxAge: 28, Debug: a.Debug, TerminalOut: true, }) if err != nil { return nil, err } logger.Info("main", "start dma handler") // Initialize dtabase manager handler dmaHandler := DBMHandler{ arg: a, filePath: fmt.Sprintf("%s/%s.dbm", a.RootDir, a.DBMFile), Log: logger, Conns: serverModels.NewConnections(), } // initialize system datapoint and periodically update it if err := dmaHandler.AddSystemDps(); err != nil { return nil, err } // check if dtabase file exists to load data s := time.Now() if _, err := os.Stat(dmaHandler.filePath); err == nil { f, err := os.Open(dmaHandler.filePath) if err != nil { return nil, err } defer f.Close() // read in dtaabase file content scanner := bufio.NewScanner(f) for scanner.Scan() { dp := models.Datapoint{} if err = json.Unmarshal(scanner.Bytes(), &dp); err != nil { return nil, err } dmaHandler.ImportDatapoints(dp) } } dmaHandler.Log.Info("dmbHandler.NewDmbHandler", fmt.Sprintf("%d datapoint imported in %v", dmaHandler.GetNumbersOfDatapoints(), time.Since(s))) return &dmaHandler, nil } func (d *DBMHandler) SaveDb() (err error) { f, err := os.OpenFile(d.filePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666) if err != nil { return err } defer f.Close() for _, dp := range d.DB.GetAllDatapoints(0) { //exclude System datapoints from saving //System datapoints are used for internal purposes and should not be saved in the database if strings.Contains(dp.Path, "System:") { continue } b, er := json.Marshal(dp) if er != nil { return er } _, err = f.Write(b) if err != nil { return } _, err = f.Write([]byte("\n")) if err != nil { return } } return } func (d *DBMHandler) CreateDatapoints(sets ...json_dataModels.Set) ([]json_dataModels.Set, error) { if len(sets) == 0 { return nil, nil } dps, err := d.DB.CreateDatapoints(d.Conns, sets...) if err != nil { return nil, err } var ndp uint64 for _, dp := range dps { if !dp.Updated { ndp++ } } dp := d.QueryDatapoints(1, "System:Datapoints") d.UpdateDatapointValue("System:Datapoints", dp[0].GetValueUint64()+ndp) return dps, nil } func (d *DBMHandler) ImportDatapoints(dps ...models.Datapoint) error { for _, dp := range dps { err := d.DB.ImportDatapoint(d.Conns, dp, dp.Path) if err != nil { return err } dps := d.QueryDatapoints(1, "System:Datapoints") d.UpdateDatapointValue("System:Datapoints", dps[0].GetValueUint64()+1) } return nil } func (d *DBMHandler) UpdateDatapointValue(path string, value any) error { return d.DB.UpdateDatapointValue(d.Conns, value, path) } func (d *DBMHandler) RemoveDatapoint(sets ...json_dataModels.Set) ([]json_dataModels.Set, error) { var lsRemoved []json_dataModels.Set for _, set := range sets { removed, err := d.DB.RemoveDatapoint(d.Conns, set) if err != nil { return lsRemoved, err } lsRemoved = append(lsRemoved, removed) dp := d.QueryDatapoints(1, "System:Datapoints") d.UpdateDatapointValue("System:Datapoints", dp[0].GetValueUint64()-1) } return lsRemoved, nil } func (d *DBMHandler) QueryDatapoints(depth uint, key string) []*models.Datapoint { return d.DB.QueryDatapoints(depth, key) }