2 Copyright (c) 2019 AT&T Intellectual Property.
3 Copyright (c) 2018-2019 Nokia.
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
24 "gerrit.oran-osc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
27 type iDatabase interface {
28 MSet(pairs ...interface{}) error
29 MGet(keys []string) ([]interface{}, error)
31 Del(keys []string) error
32 Keys(key string) ([]string, error)
33 SetIE(key string, oldData, newData interface{}) (bool, error)
34 SetNX(key string, data interface{}) (bool, error)
35 DelIE(key string, data interface{}) (bool, error)
38 type SdlInstance struct {
44 //NewDatabase creates a connection to database that will be used
45 //as a backend for the key-value storage. The returned value shall
46 //be given as a parameter when calling NewKeyValStorage
47 func NewDatabase() *sdlgoredis.DB {
48 db := sdlgoredis.Create()
52 //NewSdlInstance creates a new sdl instance using the given namespace.
53 //The database used as a backend is given as a parameter
54 func NewSdlInstance(NameSpace string, db iDatabase) *SdlInstance {
57 nsPrefix: "{" + NameSpace + "},",
64 func (s *SdlInstance) Close() error {
68 func (s *SdlInstance) setNamespaceToKeys(pairs ...interface{}) []interface{} {
69 var retVal []interface{}
70 for i, v := range pairs {
72 reflectType := reflect.TypeOf(v)
73 switch reflectType.Kind() {
75 x := reflect.ValueOf(v)
76 for i2 := 0; i2 < x.Len(); i2++ {
78 retVal = append(retVal, s.nsPrefix+x.Index(i2).Interface().(string))
80 retVal = append(retVal, x.Index(i2).Interface())
84 x := reflect.ValueOf(v)
85 for i2 := 0; i2 < x.Len(); i2++ {
87 retVal = append(retVal, s.nsPrefix+x.Index(i2).Interface().(string))
89 retVal = append(retVal, x.Index(i2).Interface())
93 retVal = append(retVal, s.nsPrefix+v.(string))
96 retVal = append(retVal, v)
102 //Set function writes data to shared data layer storage. Writing is done
103 //atomically, i.e. all succeeds or fails.
104 //Data to be written is given as key-value pairs. Several key-value
105 //pairs can be written with one call.
106 //The key is expected to be string whereas value can be anything, string,
107 //number, slice array or map
108 func (s *SdlInstance) Set(pairs ...interface{}) error {
113 keyAndData := s.setNamespaceToKeys(pairs...)
114 err := s.MSet(keyAndData...)
118 //Get function atomically reads one or more keys from SDL. The returned map has the
119 //requested keys as index and data as value. If the requested key is not found
120 //from SDL, it's value is nil
121 func (s *SdlInstance) Get(keys []string) (map[string]interface{}, error) {
122 m := make(map[string]interface{})
127 var keysWithNs []string
128 for _, v := range keys {
129 keysWithNs = append(keysWithNs, s.nsPrefix+v)
131 val, err := s.MGet(keysWithNs)
135 for i, v := range val {
141 //SetIf atomically replaces existing data with newData in SDL if data matches the oldData.
142 //If replace was done successfully, true will be returned.
143 func (s *SdlInstance) SetIf(key string, oldData, newData interface{}) (bool, error) {
144 status, err := s.SetIE(s.nsPrefix+key, oldData, newData)
151 //SetIfNotExists conditionally sets the value of a key. If key already exists in SDL,
152 //then it's value is not changed. Checking the key existence and potential set operation
153 //is done atomically.
154 func (s *SdlInstance) SetIfNotExists(key string, data interface{}) (bool, error) {
155 status, err := s.SetNX(s.nsPrefix+key, data)
162 //Remove data from SDL. Operation is done atomically, i.e. either all succeeds or fails
163 func (s *SdlInstance) Remove(keys []string) error {
168 var keysWithNs []string
169 for _, v := range keys {
170 keysWithNs = append(keysWithNs, s.nsPrefix+v)
172 err := s.Del(keysWithNs)
176 //RemoveIf removes data from SDL conditionally. If existing data matches given data,
177 //key and data are removed from SDL. If remove was done successfully, true is returned.
178 func (s *SdlInstance) RemoveIf(key string, data interface{}) (bool, error) {
179 status, err := s.DelIE(s.nsPrefix+key, data)
186 //GetAll returns all keys under the namespace. No prior knowledge about the keys in the
187 //given namespace exists, thus operation is not guaranteed to be atomic or isolated.
188 func (s *SdlInstance) GetAll() ([]string, error) {
189 keys, err := s.Keys(s.nsPrefix + "*")
190 var retVal []string = nil
194 for _, v := range keys {
195 retVal = append(retVal, strings.Split(v, s.nsPrefix)[1])
200 //RemoveAll removes all keys under the namespace. Remove operation is not atomic, thus
201 //it is not guaranteed that all keys are removed.
202 func (s *SdlInstance) RemoveAll() error {
203 keys, err := s.Keys(s.nsPrefix + "*")