mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Starting working at new navigableMap
This commit is contained in:
committed by
Dan Christian Bogos
parent
0bcb52a23f
commit
2ddfd8ae3c
272
utils/navigablemap.go
Normal file
272
utils/navigablemap.go
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DataStorage is the new DataProvider
|
||||
type DataStorage interface {
|
||||
String() string // printable version of data
|
||||
Get(fldPath []string) (interface{}, error)
|
||||
GetString(fldPath []string) (string, error)
|
||||
Set(fldPath []string, val interface{}) error
|
||||
Remove(fldPath []string) error
|
||||
GetKeys(nesteed bool) []string
|
||||
// RemoteHost() net.Addr
|
||||
}
|
||||
|
||||
// MapStorage is the basic DataStorage
|
||||
type MapStorage map[string]interface{}
|
||||
|
||||
// String returns the map as json string
|
||||
func (ms *MapStorage) String() string { return ToJSON(ms) }
|
||||
|
||||
// Get returns the value from the path
|
||||
func (ms *MapStorage) Get(fldPath []string) (val interface{}, err error) {
|
||||
if len(fldPath) == 0 {
|
||||
err = ErrNotFound
|
||||
return
|
||||
}
|
||||
var has bool
|
||||
if val, has = (*ms)[fldPath[0]]; !has {
|
||||
err = ErrNotFound
|
||||
return
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
return
|
||||
}
|
||||
ds, ok := val.(DataStorage)
|
||||
if !ok {
|
||||
err = fmt.Errorf("Wrong type")
|
||||
return
|
||||
}
|
||||
return ds.Get(fldPath[1:])
|
||||
}
|
||||
|
||||
// GetString returns thevalue from path as string
|
||||
func (ms *MapStorage) GetString(fldPath []string) (str string, err error) {
|
||||
var val interface{}
|
||||
if val, err = ms.Get(fldPath); err != nil {
|
||||
return
|
||||
}
|
||||
return IfaceAsString(val), nil
|
||||
}
|
||||
|
||||
// Set sets the value at the given path
|
||||
func (ms *MapStorage) Set(fldPath []string, val interface{}) (err error) {
|
||||
if len(fldPath) == 0 {
|
||||
return fmt.Errorf("Wrong path")
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
(*ms)[fldPath[0]] = val
|
||||
return
|
||||
}
|
||||
nMap := &MapStorage{}
|
||||
(*ms)[fldPath[0]] = nMap
|
||||
return nMap.Set(fldPath[1:], val)
|
||||
}
|
||||
|
||||
// GetKeys returns all the keys from map
|
||||
func (ms *MapStorage) GetKeys(nesteed bool) (keys []string) {
|
||||
for k, v := range *ms {
|
||||
keys = append(keys, k)
|
||||
if !nesteed {
|
||||
continue
|
||||
}
|
||||
ds, ok := v.(DataStorage)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, dsKey := range ds.GetKeys(nesteed) {
|
||||
keys = append(keys, k+NestingSep+dsKey)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the item at path
|
||||
func (ms *MapStorage) Remove(fldPath []string) (err error) {
|
||||
if len(fldPath) == 0 {
|
||||
return fmt.Errorf("Wrong path")
|
||||
}
|
||||
var val interface{}
|
||||
var has bool
|
||||
if val, has = (*ms)[fldPath[0]]; !has {
|
||||
return // ignore (already removed)
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
delete(*ms, fldPath[0])
|
||||
return
|
||||
}
|
||||
ds, ok := val.(DataStorage)
|
||||
if !ok {
|
||||
err = fmt.Errorf("Wrong type")
|
||||
return
|
||||
}
|
||||
return ds.Remove(fldPath[1:])
|
||||
}
|
||||
|
||||
// NavigableMap is a DataStorage
|
||||
type NavigableMap map[string]DataStorage
|
||||
|
||||
// String returns the map as json string
|
||||
func (nm *NavigableMap) String() string { return ToJSON(nm) }
|
||||
|
||||
// Get returns the value from the path
|
||||
func (nm *NavigableMap) Get(fldPath []string) (val interface{}, err error) {
|
||||
if len(fldPath) == 0 {
|
||||
err = ErrNotFound
|
||||
return
|
||||
}
|
||||
ds, has := (*nm)[fldPath[0]]
|
||||
if !has {
|
||||
err = ErrNotFound
|
||||
return
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
val = ds
|
||||
return
|
||||
}
|
||||
return ds.Get(fldPath[1:])
|
||||
}
|
||||
|
||||
// GetString returns thevalue from path as string
|
||||
func (nm *NavigableMap) GetString(fldPath []string) (str string, err error) {
|
||||
var val interface{}
|
||||
if val, err = nm.Get(fldPath); err != nil {
|
||||
return
|
||||
}
|
||||
return IfaceAsString(val), nil
|
||||
}
|
||||
|
||||
// Set sets the value at the given path
|
||||
func (nm *NavigableMap) Set(fldPath []string, val interface{}) (err error) {
|
||||
if len(fldPath) == 0 {
|
||||
return fmt.Errorf("Wrong path")
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
ds, ok := val.(DataStorage)
|
||||
if !ok {
|
||||
return fmt.Errorf("Wrong type")
|
||||
}
|
||||
(*nm)[fldPath[0]] = ds
|
||||
return
|
||||
}
|
||||
if _, has := (*nm)[fldPath[0]]; !has {
|
||||
(*nm)[fldPath[0]] = &MapStorage{}
|
||||
}
|
||||
return (*nm)[fldPath[0]].Set(fldPath[1:], val)
|
||||
}
|
||||
|
||||
// GetKeys returns all the keys from map
|
||||
func (nm *NavigableMap) GetKeys(nesteed bool) (keys []string) {
|
||||
for k, v := range *nm {
|
||||
keys = append(keys, k)
|
||||
if !nesteed {
|
||||
continue
|
||||
}
|
||||
for _, dsKey := range v.GetKeys(nesteed) {
|
||||
keys = append(keys, k+NestingSep+dsKey)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the item at path
|
||||
func (nm *NavigableMap) Remove(fldPath []string) (err error) {
|
||||
if len(fldPath) == 0 {
|
||||
return fmt.Errorf("Wrong path")
|
||||
}
|
||||
var val DataStorage
|
||||
var has bool
|
||||
if val, has = (*nm)[fldPath[0]]; !has {
|
||||
return // ignore (already removed)
|
||||
}
|
||||
if len(fldPath) == 1 {
|
||||
delete(*nm, fldPath[0])
|
||||
return
|
||||
}
|
||||
return val.Remove(fldPath[1:])
|
||||
}
|
||||
|
||||
// NewOrderedNavigableMap initializates a structure of OrderedNavigableMap with a NavigableMap
|
||||
func NewOrderedNavigableMap(nm *NavigableMap) *OrderedNavigableMap {
|
||||
if nm == nil {
|
||||
return &OrderedNavigableMap{
|
||||
nm: &NavigableMap{},
|
||||
order: [][]string{},
|
||||
}
|
||||
}
|
||||
keys := nm.GetKeys(true)
|
||||
order := make([][]string, len(keys))
|
||||
for i, k := range keys {
|
||||
order[i] = strings.Split(k, NestingSep)
|
||||
}
|
||||
return &OrderedNavigableMap{
|
||||
nm: nm,
|
||||
order: order,
|
||||
}
|
||||
}
|
||||
|
||||
// OrderedNavigableMap is the same as NavigableMap but keeps the order of fields
|
||||
type OrderedNavigableMap struct {
|
||||
nm *NavigableMap
|
||||
order [][]string
|
||||
}
|
||||
|
||||
// String returns the map as json string
|
||||
func (onm *OrderedNavigableMap) String() string { return ToJSON(onm.nm) }
|
||||
|
||||
// Get returns the value from the path
|
||||
func (onm *OrderedNavigableMap) Get(fldPath []string) (val interface{}, err error) {
|
||||
return onm.nm.Get(fldPath)
|
||||
}
|
||||
|
||||
// GetString returns thevalue from path as string
|
||||
func (onm *OrderedNavigableMap) GetString(fldPath []string) (str string, err error) {
|
||||
return onm.nm.GetString(fldPath)
|
||||
}
|
||||
|
||||
// Set sets the value at the given path
|
||||
func (onm *OrderedNavigableMap) Set(fldPath []string, val interface{}) (err error) {
|
||||
if err = onm.nm.Set(fldPath, val); err == nil {
|
||||
onm.order = append(onm.order, fldPath)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetKeys returns all the keys from map
|
||||
func (onm *OrderedNavigableMap) GetKeys(nesteed bool) (keys []string) {
|
||||
keys = make([]string, len(onm.order))
|
||||
for i, k := range onm.order {
|
||||
keys[i] = strings.Join(k, NestingSep)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Remove removes the item at path
|
||||
func (onm *OrderedNavigableMap) Remove(fldPath []string) (err error) {
|
||||
if len(fldPath) == 0 {
|
||||
return fmt.Errorf("Wrong path")
|
||||
}
|
||||
return onm.nm.Remove(fldPath)
|
||||
}
|
||||
Reference in New Issue
Block a user