blob: 3377e6d5937b3717b036a7a1350a8ed66fde6132 [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>
kurtis.heimerlbcf60a82012-10-26 06:25:56 +000036#include <syslog.h>
dburgess82c46ff2011-10-07 02:40:51 +000037
38#include <map>
39#include <vector>
40#include <string>
41#include <iostream>
42
43#include <Threads.h>
44#include <stdint.h>
45
46
47/** A class for configuration file errors. */
48class ConfigurationTableError {};
kurtis.heimerlbcf60a82012-10-26 06:25:56 +000049extern char gCmdName[]; // Gotta be global, gotta be char*, gotta love it.
dburgess82c46ff2011-10-07 02:40:51 +000050
51/** An exception thrown when a given config key isn't found. */
52class ConfigurationTableKeyNotFound : public ConfigurationTableError {
53
54 private:
55
56 std::string mKey;
57
58 public:
59
60 ConfigurationTableKeyNotFound(const std::string& wKey)
61 :mKey(wKey)
kurtis.heimerlbcf60a82012-10-26 06:25:56 +000062 { }
dburgess82c46ff2011-10-07 02:40:51 +000063
64 const std::string& key() const { return mKey; }
65
66};
67
68
69class ConfigurationRecord {
70
71 private:
72
73 std::string mValue;
74 long mNumber;
75 bool mDefined;
76
77 public:
78
79 ConfigurationRecord(bool wDefined=true):
80 mDefined(wDefined)
81 { }
82
83 ConfigurationRecord(const std::string& wValue):
84 mValue(wValue),
85 mNumber(strtol(wValue.c_str(),NULL,0)),
86 mDefined(true)
87 { }
88
89 ConfigurationRecord(const char* wValue):
90 mValue(std::string(wValue)),
91 mNumber(strtol(wValue,NULL,0)),
92 mDefined(true)
93 { }
94
95
96 const std::string& value() const { return mValue; }
97 long number() const { return mNumber; }
98 bool defined() const { return mDefined; }
99
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000100 float floatNumber() const;
101
dburgess82c46ff2011-10-07 02:40:51 +0000102};
103
104
105/** A string class that uses a hash function for comparison. */
106class HashString : public std::string {
107
108
109 protected:
110
111 uint64_t mHash;
112
113 void computeHash();
114
115
116 public:
117
118 HashString(const char* src)
119 :std::string(src)
120 {
121 computeHash();
122 }
123
124 HashString(const std::string& src)
125 :std::string(src)
126 {
127 computeHash();
128 }
129
130 HashString()
131 {
132 mHash=0;
133 }
134
135 HashString& operator=(std::string& src)
136 {
137 std::string::operator=(src);
138 computeHash();
139 return *this;
140 }
141
142 HashString& operator=(const char* src)
143 {
144 std::string::operator=(src);
145 computeHash();
146 return *this;
147 }
148
149 bool operator==(const HashString& other)
150 {
151 return mHash==other.mHash;
152 }
153
154 bool operator<(const HashString& other)
155 {
156 return mHash<other.mHash;
157 }
158
159 bool operator>(const HashString& other)
160 {
161 return mHash<other.mHash;
162 }
163
164 uint64_t hash() const { return mHash; }
165
166};
167
168
169typedef std::map<HashString, ConfigurationRecord> ConfigurationMap;
170
171
172/**
173 A class for maintaining a configuration key-value table,
174 based on sqlite3 and a local map-based cache.
175 Thread-safe, too.
176*/
177class ConfigurationTable {
178
179 private:
180
181 sqlite3* mDB; ///< database connection
182 ConfigurationMap mCache; ///< cache of recently access configuration values
183 mutable Mutex mLock; ///< control for multithreaded access to the cache
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000184 int mFacility;
dburgess82c46ff2011-10-07 02:40:51 +0000185
186 public:
187
188
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000189 ConfigurationTable(const char* filename = ":memory:", const char *wCmdName = 0, int wFacility = LOG_USER);
dburgess82c46ff2011-10-07 02:40:51 +0000190
191 /** Return true if the key is used in the table. */
192 bool defines(const std::string& key);
193
194 /** Return true if this key is identified as static. */
195 bool isStatic(const std::string& key) const;
196
197 /** Return true if this key is identified as required (!optional). */
198 bool isRequired(const std::string& key) const;
199
200 /**
201 Get a string parameter from the table.
202 Throw ConfigurationTableKeyNotFound if not found.
203 */
204 std::string getStr(const std::string& key);
205
206
207 /**
208 Get a string parameter from the table.
209 Define the parameter to the default value if not found.
210 */
211 std::string getStr(const std::string& key, const char* defaultValue);
212
213
214 /**
215 Get a numeric parameter from the table.
216 Throw ConfigurationTableKeyNotFound if not found.
217 */
218 long getNum(const std::string& key);
219
220 /**
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000221 Get a boolean from the table.
222 Return false if NULL or 0, true otherwise.
223 */
224 bool getBool(const std::string& key);
225
226 /**
dburgess82c46ff2011-10-07 02:40:51 +0000227 Get a numeric parameter from the table.
228 Define the parameter to the default value if not found.
229 */
230 long getNum(const std::string& key, long defaultValue);
231
232 /**
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000233 Get a vector of strings from the table.
234 */
235 std::vector<std::string> getVectorOfStrings(const std::string& key);
236
237 /**
238 Get a vector of strings from the table, with a default value..
239 */
240 std::vector<std::string> getVectorOfStrings(const std::string& key, const char* defaultValue);
241
242 /**
243 Get a float from the table.
244 Throw ConfigurationTableKeyNotFound if not found.
245 */
246 float getFloat(const std::string& key);
247
248 /**
dburgess82c46ff2011-10-07 02:40:51 +0000249 Get a numeric vector from the table.
250 */
251 std::vector<unsigned> getVector(const std::string& key);
252
253 /** Get length of a vector */
254 unsigned getVectorLength(const std::string &key)
255 { return getVector(key).size(); }
256
257 /** Set or change a value in the table. */
258 bool set(const std::string& key, const std::string& value);
259
260 /** Set or change a value in the table. */
261 bool set(const std::string& key, long value);
262
263 /** Create an entry in the table, no value though. */
264 bool set(const std::string& key);
265
266 /**
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000267 Set a corresponding value to NULL.
268 Will not alter required values.
269 @param key The key of the item to be nulled-out.
270 @return true if anything was actually nulled-out.
dburgess82c46ff2011-10-07 02:40:51 +0000271 */
272 bool unset(const std::string& key);
273
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000274 /**
275 Remove an entry from the table.
276 Will not alter required values.
277 @param key The key of the item to be removed.
278 @return true if anything was actually removed.
279 */
280 bool remove(const std::string& key);
281
dburgess82c46ff2011-10-07 02:40:51 +0000282 /** Search the table, dumping to a stream. */
283 void find(const std::string& pattern, std::ostream&) const;
284
285 /** Define the callback to purge the cache whenever the database changes. */
286 void setUpdateHook(void(*)(void *,int ,char const *,char const *,sqlite3_int64));
287
288 /** purege cache if it exceeds a certain age */
289 void checkCacheAge();
290
291 /** Delete all records from the cache. */
292 void purge();
293
294
295 private:
296
297 /**
298 Attempt to lookup a record, cache if needed.
299 Throw ConfigurationTableKeyNotFound if not found.
300 Caller should hold mLock because the returned reference points into the cache.
301 */
302 const ConfigurationRecord& lookup(const std::string& key);
303
304};
305
306
kurtis.heimerlbcf60a82012-10-26 06:25:56 +0000307typedef std::map<HashString, std::string> HashStringMap;
308
309class SimpleKeyValue {
310
311 protected:
312
313 HashStringMap mMap;
314
315 public:
316
317 /** Take a C string "A=B" and set map["A"]="B". */
318 void addItem(const char*);
319
320 /** Take a C string "A=B C=D E=F ..." and add all of the pairs to the map. */
321 void addItems(const char*s);
322
323 /** Return a reference to the string at map["key"]. */
324 const char* get(const char*) const;
325};
326
327
dburgess82c46ff2011-10-07 02:40:51 +0000328
329#endif
330
331
332// vim: ts=4 sw=4