-
Notifications
You must be signed in to change notification settings - Fork 47
/
cassa_broker_impl.go
130 lines (111 loc) · 4.42 KB
/
cassa_broker_impl.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2017 Cisco and/or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cassandra
import (
"github.com/willfaught/gockle"
"go.ligato.io/cn-infra/v2/db/sql"
"go.ligato.io/cn-infra/v2/utils/structs"
)
// NewBrokerUsingSession is a Broker constructor. Use it like this:
//
// session := gockle.NewSession(gocql.NewCluster("172.17.0.1"))
// defer db.Close()
// db := NewBrokerUsingSession(session)
// db.ListValues(...)
func NewBrokerUsingSession(gocqlSession gockle.Session) *BrokerCassa {
return &BrokerCassa{session: gocqlSession}
}
// BrokerCassa implements interface db.Broker. This implementation simplifies work with gocql in the way
// that it is not need to write "SQL" queries. But the "SQL" is not really hidden, one can use it if needed.
// The "SQL" queries are generated from the go structures (see more details in Put, Delete, Key, GetValue, ListValues).
type BrokerCassa struct {
session gockle.Session
}
// ValIterator is an iterator returned by ListValues call
type ValIterator struct {
Delegate gockle.Iterator
}
// ErrIterator is an iterator that stops immediately and just returns last error on Close()
type ErrIterator struct {
LastError error
}
// Put - see the description in interface sql.Broker.Put().
// Put generates statement & binding for gocql Exec().
// Any error returned from gockle.Session.Exec is propagated upwards.
func (pdb *BrokerCassa) Put(where sql.Expression, pointerToAStruct interface{} /*TODO TTL, opts ...datasync.PutOption*/) error {
statement, bindings, err := PutExpToString(where, pointerToAStruct)
if err != nil {
return err
}
return pdb.session.Exec(statement, bindings...)
}
// Exec - see the description in interface sql.Broker.ExecPut()
// Exec runs statement (AS-IS) using gocql
func (pdb *BrokerCassa) Exec(statement string, binding ...interface{}) error {
return pdb.session.Exec(statement, binding...)
}
// Delete - see the description in interface sql.Broker.ExecPut()
// Delete generates statement & binding for gocql Exec()
func (pdb *BrokerCassa) Delete(fromWhere sql.Expression) error {
statement, bindings, err := ExpToString(fromWhere)
if err != nil {
return err
}
return pdb.session.Exec("DELETE"+statement, bindings...)
}
// GetValue - see the description in interface sql.Broker.GetValue()
// GetValue just iterate once for ListValues()
func (pdb *BrokerCassa) GetValue(query sql.Expression, reqObj interface{}) (found bool, err error) {
it := pdb.ListValues(query)
stop := it.GetNext(reqObj)
return !stop, it.Close()
}
// ListValues retrieves an iterator for elements stored under the provided key.
// ListValues runs query (AS-IS) using gocql Scan Iterator.
func (pdb *BrokerCassa) ListValues(query sql.Expression) sql.ValIterator {
queryStr, binding, err := SelectExpToString(query)
if err != nil {
return &ErrIterator{err}
}
it := pdb.session.ScanIterator(queryStr, binding...)
return &ValIterator{it}
}
// GetNext returns the following item from the result set. If data was returned, found is set to true.
// argument "outVal" can be:
// - pointer to structure
// - map
func (it *ValIterator) GetNext(outVal interface{}) (stop bool) {
if m, ok := outVal.(map[string]interface{}); ok {
ok = it.Delegate.ScanMap(m)
return !ok //if not ok than stop
}
_, ptrs := structs.ListExportedFieldsPtrs(outVal, cqlExported)
ok := it.Delegate.Scan(ptrs...)
return !ok //if not ok than stop
}
// Close the iterator. Note, the error is important (may occure during marshalling/un-marshalling)
func (it *ValIterator) Close() error {
return it.Delegate.Close()
}
// GetNext returns the following item from the result set. If data was returned, found is set to true.
// argument "outVal" can be:
// - pointer to structure
// - map
func (it *ErrIterator) GetNext(outVal interface{}) (stop bool) {
return true
}
// Close the iterator. Note, the error is important (may occure during marshalling/un-marshalling)
func (it *ErrIterator) Close() error {
return it.LastError
}