aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/util/key_value_store.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/util/key_value_store.go')
-rw-r--r--src/gnunet/util/key_value_store.go188
1 files changed, 0 insertions, 188 deletions
diff --git a/src/gnunet/util/key_value_store.go b/src/gnunet/util/key_value_store.go
deleted file mode 100644
index 0658218..0000000
--- a/src/gnunet/util/key_value_store.go
+++ /dev/null
@@ -1,188 +0,0 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019, 2020 Bernd Fix >Y<
3//
4// gnunet-go is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License as published
6// by the Free Software Foundation, either version 3 of the License,
7// or (at your option) any later version.
8//
9// gnunet-go is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17// SPDX-License-Identifier: AGPL3.0-or-later
18
19package util
20
21import (
22 "context"
23 "database/sql"
24 "fmt"
25 "strconv"
26 "strings"
27
28 redis "github.com/go-redis/redis/v8"
29)
30
31// Error messages related to the key/value-store implementations
32var (
33 ErrKVSInvalidSpec = fmt.Errorf("Invalid KVStore specification")
34 ErrKVSNotAvailable = fmt.Errorf("KVStore not available")
35)
36
37// KeyValueStore interface for implementations that store and retrieve
38// key/value pairs. Keys and values are strings.
39type KeyValueStore interface {
40 Put(key string, value string) error // put a key/value pair into store
41 Get(key string) (string, error) // retrieve a value for a key from store
42 List() ([]string, error) // get all keys from the store
43}
44
45// OpenKVStore opens a key/value store for further put/get operations.
46// The 'spec' option specifies the arguments required to connect to a specific
47// persistence mechanism. The arguments in the 'spec' string are separated by
48// the '+' character.
49// The first argument specifies the type of key/value store to be used; the
50// meaning and format of the following arguments depend on this type.
51//
52// Key/Value Store types defined:
53// * 'redis': Use a Redis server for persistance; the specification is
54// "redis+addr+[passwd]+db". 'db' must be an integer value.
55// * 'mysql': MySQL-compatible database (see 'database.go' for details)
56// * 'sqlite3': SQLite3-compatible database (see 'database.go' for details)
57func OpenKVStore(spec string) (KeyValueStore, error) {
58 // check specification string
59 specs := strings.Split(spec, "+")
60 if len(specs) < 2 {
61 return nil, ErrKVSInvalidSpec
62 }
63 switch specs[0] {
64 case "redis":
65 //--------------------------------------------------------------
66 // NoSQL-based persistance
67 //--------------------------------------------------------------
68 if len(specs) < 4 {
69 return nil, ErrKVSInvalidSpec
70 }
71 db, err := strconv.Atoi(specs[3])
72 if err != nil {
73 return nil, ErrKVSInvalidSpec
74 }
75 kvs := new(KvsRedis)
76 kvs.db = db
77 kvs.client = redis.NewClient(&redis.Options{
78 Addr: specs[1],
79 Password: specs[2],
80 DB: db,
81 })
82 if kvs.client == nil {
83 err = ErrKVSNotAvailable
84 }
85 return kvs, err
86
87 case "sqlite3", "mysql":
88 //--------------------------------------------------------------
89 // SQL-based persistance
90 //--------------------------------------------------------------
91 kvs := new(KvsSQL)
92 var err error
93
94 // connect to SQL database
95 kvs.db, err = ConnectSQLDatabase(spec)
96 if err != nil {
97 return nil, err
98 }
99 // get number of key/value pairs (as a check for existing table)
100 row := kvs.db.QueryRow("select count(*) from store")
101 var num int
102 if row.Scan(&num) != nil {
103 return nil, ErrKVSNotAvailable
104 }
105 return kvs, nil
106 }
107 return nil, ErrKVSInvalidSpec
108}
109
110//======================================================================
111// NoSQL-based key-value-stores
112//======================================================================
113
114// KvsRedis represents a redis-based key/value store
115type KvsRedis struct {
116 client *redis.Client // client connection
117 db int // index to database
118}
119
120// Put a key/value pair into the store
121func (kvs *KvsRedis) Put(key string, value string) error {
122 return kvs.client.Set(context.TODO(), key, value, 0).Err()
123}
124
125// Get a value for a given key from store
126func (kvs *KvsRedis) Get(key string) (value string, err error) {
127 return kvs.client.Get(context.TODO(), key).Result()
128}
129
130// List all keys in store
131func (kvs *KvsRedis) List() (keys []string, err error) {
132 var (
133 crs uint64
134 segm []string
135 ctx = context.TODO()
136 )
137 for {
138 segm, crs, err = kvs.client.Scan(ctx, crs, "*", 10).Result()
139 if err != nil {
140 return nil, err
141 }
142 if crs == 0 {
143 break
144 }
145 keys = append(keys, segm...)
146 }
147 return
148}
149
150//======================================================================
151// SQL-based key-value-store
152//======================================================================
153
154// KvsSQL represents a SQL-based key/value store
155type KvsSQL struct {
156 db *sql.DB
157}
158
159// Put a key/value pair into the store
160func (kvs *KvsSQL) Put(key string, value string) error {
161 _, err := kvs.db.Exec("insert into store(key,value) values(?,?)", key, value)
162 return err
163}
164
165// Get a value for a given key from store
166func (kvs *KvsSQL) Get(key string) (value string, err error) {
167 row := kvs.db.QueryRow("select value from store where key=?", key)
168 err = row.Scan(&value)
169 return
170}
171
172// List all keys in store
173func (kvs *KvsSQL) List() (keys []string, err error) {
174 var (
175 rows *sql.Rows
176 key string
177 )
178 rows, err = kvs.db.Query("select key from store")
179 if err == nil {
180 for rows.Next() {
181 if err = rows.Scan(&key); err != nil {
182 break
183 }
184 keys = append(keys, key)
185 }
186 }
187 return
188}