blob: bc37a498cd3aa367699b9b4fe8eaa8cc4ddcc301 [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2009, 2010 Free Software Foundation, Inc.
kurtis.heimerldb70eb42012-12-16 06:06:32 +00003* Copyright 2010 Kestrel Signal Processing, Inc.
4* Copyright 2011, 2012 Range Networks, Inc.
dburgess82c46ff2011-10-07 02:40:51 +00005*
6* This software is distributed under the terms of the GNU Affero Public License.
7* See the COPYING file in the main directory for details.
8*
9* This use of this software may be subject to additional restrictions.
10* See the LEGAL file in the main directory for details.
11
12 This program is free software: you can redistribute it and/or modify
13 it under the terms of the GNU Affero General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Affero General Public License for more details.
21
22 You should have received a copy of the GNU Affero General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25*/
26
27
28#ifndef CONFIGURATION_H
29#define CONFIGURATION_H
30
31
32#include "sqlite3util.h"
33
34#include <assert.h>
35#include <stdlib.h>
36
37#include <map>
38#include <vector>
39#include <string>
40#include <iostream>
41
42#include <Threads.h>
43#include <stdint.h>
44
45
46/** A class for configuration file errors. */
47class ConfigurationTableError {};
kurtis.heimerlbcf60a82012-10-26 06:25:56 +000048extern char gCmdName[]; // Gotta be global, gotta be char*, gotta love it.
dburgess82c46ff2011-10-07 02:40:51 +000049
50/** An exception thrown when a given config key isn't found. */
51class ConfigurationTableKeyNotFound : public ConfigurationTableError {
52
53 private:
54
55 std::string mKey;
56
57 public:
58
59 ConfigurationTableKeyNotFound(const std::string& wKey)
60 :mKey(wKey)
kurtis.heimerlbcf60a82012-10-26 06:25:56 +000061 { }
dburgess82c46ff2011-10-07 02:40:51 +000062
63 const std::string& key() const { return mKey; }
64
65};
66
67
68class ConfigurationRecord {
69
70 private:
71
72 std::string mValue;
73 long mNumber;
74 bool mDefined;
75
76 public:
77
78 ConfigurationRecord(bool wDefined=true):
79 mDefined(wDefined)
80 { }
81
82 ConfigurationRecord(const std::string& wValue):
83 mValue(wValue),
84 mNumber(strtol(wValue.c_str(),NULL,0)),
85 mDefined(true)
86 { }
87
88 ConfigurationRecord(const char* wValue):
89 mValue(std::string(wValue)),
90 mNumber(strtol(wValue,NULL,0)),
91 mDefined(true)
92 { }
93
94
95 const std::string& value() const { return mValue; }
96 long number() const { return mNumber; }
97 bool defined() const { return mDefined; }
98
kurtis.heimerlbcf60a82012-10-26 06:25:56 +000099 float floatNumber() const;
100
dburgess82c46ff2011-10-07 02:40:51 +0000101};
102
103
104/** A string class that uses a hash function for comparison. */
105class HashString : public std::string {
106
107
108 protected:
109
110 uint64_t mHash;
111
112 void computeHash();
113
114
115 public:
116
117 HashString(const char* src)
118 :std::string(src)
119 {
120 computeHash();
121 }
122
123 HashString(const std::string& src)
124 :std::string(src)
125 {
126 computeHash();
127 }
128
129 HashString()
130 {
131 mHash=0;
132 }
133
134 HashString& operator=(std::string& src)
135 {
136 std::string::operator=(src);
137 computeHash();
138 return *this;
139 }
140
141 HashString& operator=(const char* src)
142 {
143 std::string::operator=(src);
144 computeHash();
145 return *this;
146 }
147
148 bool operator==(const HashString& other)
149 {
150 return mHash==other.mHash;
151 }
152
153 bool operator<(const HashString& other)
154 {
155 return mHash<other.mHash;
156 }
157
158 bool operator>(const HashString& other)
159 {
160 return mHash<other.mHash;
161 }
162
163 uint64_t hash() const { return mHash; }
164
165};
166
167
168typedef std::map<HashString, ConfigurationRecord> ConfigurationMap;
169
170
171/**
172 A class for maintaining a configuration key-value table,
173 based on sqlite3 and a local map-based cache.
174 Thread-safe, too.
175*/
176class ConfigurationTable {
177
178 private:
179
180 sqlite3* mDB; ///< database connection
181 ConfigurationMap mCache; ///< cache of recently access configuration values
182 mutable Mutex mLock; ///< control for multithreaded access to the cache
183
184 public:
185
186
kurtis.heimerl00913d72012-12-16 06:08:18 +0000187 ConfigurationTable(const char* filename = ":memory:", const char *wCmdName = 0);
dburgess82c46ff2011-10-07 02:40:51 +0000188
189 /** Return true if the key is used in the table. */
190 bool defines(const std::string& key);
191
192 /** Return true if this key is identified as static. */
193 bool isStatic(const std::string& key) const;
194
195 /** Return true if this key is identified as required (!optional). */
196 bool isRequired(const std::string& key) const;
197
198 /**
199 Get a string parameter from the table.
200 Throw ConfigurationTableKeyNotFound if not found.
201 */
202 std::string getStr(const std::string& key);
203
204
205 /**
206 Get a string parameter from the table.
207 Define the parameter to the default value if not found.
208 */
209 std::string getStr(const std::string& key, const char* defaultValue);
210
211
212 /**
213 Get a numeric parameter from the table.
214 Throw ConfigurationTableKeyNotFound if not found.
215 */
216 long getNum(const std::string& key);
217
218 /**
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000219 Get a boolean from the table.
220 Return false if NULL or 0, true otherwise.
221 */
222 bool getBool(const std::string& key);
223
224 /**
dburgess82c46ff2011-10-07 02:40:51 +0000225 Get a numeric parameter from the table.
226 Define the parameter to the default value if not found.
227 */
228 long getNum(const std::string& key, long defaultValue);
229
230 /**
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000231 Get a vector of strings from the table.
232 */
233 std::vector<std::string> getVectorOfStrings(const std::string& key);
234
235 /**
236 Get a vector of strings from the table, with a default value..
237 */
238 std::vector<std::string> getVectorOfStrings(const std::string& key, const char* defaultValue);
239
240 /**
241 Get a float from the table.
242 Throw ConfigurationTableKeyNotFound if not found.
243 */
244 float getFloat(const std::string& key);
245
246 /**
dburgess82c46ff2011-10-07 02:40:51 +0000247 Get a numeric vector from the table.
248 */
249 std::vector<unsigned> getVector(const std::string& key);
250
251 /** Get length of a vector */
252 unsigned getVectorLength(const std::string &key)
253 { return getVector(key).size(); }
254
255 /** Set or change a value in the table. */
256 bool set(const std::string& key, const std::string& value);
257
258 /** Set or change a value in the table. */
259 bool set(const std::string& key, long value);
260
261 /** Create an entry in the table, no value though. */
262 bool set(const std::string& key);
263
264 /**
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000265 Set a corresponding value to NULL.
266 Will not alter required values.
267 @param key The key of the item to be nulled-out.
268 @return true if anything was actually nulled-out.
dburgess82c46ff2011-10-07 02:40:51 +0000269 */
270 bool unset(const std::string& key);
271
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000272 /**
273 Remove an entry from the table.
274 Will not alter required values.
275 @param key The key of the item to be removed.
276 @return true if anything was actually removed.
277 */
278 bool remove(const std::string& key);
279
dburgess82c46ff2011-10-07 02:40:51 +0000280 /** Search the table, dumping to a stream. */
281 void find(const std::string& pattern, std::ostream&) const;
282
283 /** Define the callback to purge the cache whenever the database changes. */
284 void setUpdateHook(void(*)(void *,int ,char const *,char const *,sqlite3_int64));
285
286 /** purege cache if it exceeds a certain age */
287 void checkCacheAge();
288
289 /** Delete all records from the cache. */
290 void purge();
291
292
293 private:
294
295 /**
296 Attempt to lookup a record, cache if needed.
297 Throw ConfigurationTableKeyNotFound if not found.
298 Caller should hold mLock because the returned reference points into the cache.
299 */
300 const ConfigurationRecord& lookup(const std::string& key);
301
302};
303
304
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000305typedef std::map<HashString, std::string> HashStringMap;
306
307class SimpleKeyValue {
308
309 protected:
310
311 HashStringMap mMap;
312
313 public:
314
315 /** Take a C string "A=B" and set map["A"]="B". */
316 void addItem(const char*);
317
318 /** Take a C string "A=B C=D E=F ..." and add all of the pairs to the map. */
319 void addItems(const char*s);
320
321 /** Return a reference to the string at map["key"]. */
322 const char* get(const char*) const;
323};
324
325
dburgess82c46ff2011-10-07 02:40:51 +0000326
327#endif
328
329
330// vim: ts=4 sw=4